Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
AlphaFoxz committed Nov 14, 2024
1 parent 5a6cdf3 commit db5d4f4
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 126 deletions.
10 changes: 7 additions & 3 deletions libs/domain-server/__tests__/common.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ import { expect, it } from '@jest/globals'
import { Utils } from '..'

it('createPromiseCallback 成功', async () => {
const { promise, resolved, callback, error } = Utils.createPromiseCallback(() => {})
const { promise, resolved, callback, error } = Utils.createPromiseCallback(() => {
const a = true
if (!a) {
return new Error('error')
}
})
callback()
const result = await promise
await promise
expect(resolved.value).toBe(true)
expect(error.value).toBe(undefined)
expect(result.success).toBe(true)
})
58 changes: 43 additions & 15 deletions libs/domain-server/__tests__/event.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { it, expect } from '@jest/globals'
import { createBroadcastEvent, createRequestEvent } from '../event'
import { ref, reactive } from '@vue/reactivity'
import { ref } from '@vue/reactivity'

it('createChannelEvent 触发事件', async () => {
function register() {
Expand Down Expand Up @@ -46,40 +46,68 @@ it('createChannelEvent 函数的回调', async () => {
})

it('createChannelEvent Promise的回调', async () => {
const listenerCounter = reactive<string[]>([])
const listenerCounter = ref(0)
let succeed = false
function createInitEvent() {
const event = createRequestEvent({}, (name: string) => {
if (name !== 'Andy') {
return new Error('incorrect name')
}
listenerCounter.value++
succeed = true
})
return event
}
const watchedEventsCounter = ref(0)
const initEvent = createInitEvent()
initEvent.toApi().watchPublishRequest(({ reply }) => {
watchedEventsCounter.value++
reply('Andy')
})
initEvent.toApi().watchPublishRequest(({ reply }) => {
watchedEventsCounter.value++
reply('Andy')
})
await initEvent.publishRequest({ name: 'Andy' })
expect(succeed).toBe(true)
expect(listenerCounter.value).toBe(1)
expect(watchedEventsCounter.value).toBe(1)
})

it('createChannelEvent Promise的回调', async () => {
const listenerCounter = ref(0)
let succeed = false
function createInitEvent() {
const name = ref('wong')
const event = createRequestEvent({ name }, (b: boolean) => {
listenerCounter.push('')
succeed = b
const start = Date.now()
while (Date.now() - start < 10) {
// 运行10ms
const event = createRequestEvent({ name }, (name: string) => {
if (name !== 'Andy') {
return new Error('incorrect name')
}
listenerCounter.value++
succeed = true
})
return event
}
const watchedEventsCounter = reactive<string[]>([])
const watchedEventsCounter = ref(0)
const initEvent = createInitEvent()
initEvent.toApi().watchPublishRequest(({ data, reply }) => {
watchedEventsCounter.push('')
watchedEventsCounter.value++
if (data.name === 'Andy') {
succeed = true
}
reply(true)
reply('Andy')
})
initEvent.toApi().watchPublishRequest(({ data, reply }) => {
watchedEventsCounter.push('')
watchedEventsCounter.value++
if (data.name === 'Andy') {
succeed = true
}
reply(true)
reply('Andy')
})
await initEvent.publishRequest({ name: 'Andy' })
expect(succeed).toBe(true)
expect(listenerCounter.length).toBe(1)
expect(watchedEventsCounter.length).toBe(1)
expect(listenerCounter.value).toBe(1)
expect(watchedEventsCounter.value).toBe(1)
})

it('createBroadcastEvent Promise的回调', async () => {
Expand Down
6 changes: 3 additions & 3 deletions libs/domain-server/agg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
DomainEvent,
DomainRequestEvent,
} from './event'
import { type Result, createPromiseCallback } from './common'
import { createPromiseCallback } from './common'

type AddDestroyedEvent<T extends object, K = 'destroyed'> = keyof T extends never
? { destroyed: DomainBroadcastEvent<{}> }
Expand Down Expand Up @@ -189,7 +189,7 @@ export function createUnmountableAgg<
onCreated: (fn: () => void) => void
onBeforeInitialize: (fn: () => void) => void
initialized: ComputedRef<boolean>
untilInitialized: Promise<Result<undefined>>
untilInitialized: Promise<void>
}) => {
states?: STATES
actions?: ACTIONS
Expand Down Expand Up @@ -265,7 +265,7 @@ export function createAgg<
onCreated: (fn: () => void) => void
onBeforeInitialize: (fn: () => void) => void
initialized: ComputedRef<boolean>
untilInitialized: Promise<Result<undefined>>
untilInitialized: Promise<void>
}) => {
states?: STATES
actions?: ACTIONS
Expand Down
59 changes: 20 additions & 39 deletions libs/domain-server/common.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,46 @@
import { type Ref, ref } from '@vue/reactivity'

type InferPromiseResult<T extends (...args: any[]) => any> = Exclude<ReturnType<T>, Error> extends
| undefined
| null
| void
| unknown
? { success: boolean; value: undefined; error?: Error }
: { success: boolean; value: ReturnType<T>['value']; error?: Error }

export type Result<T> = { success: boolean; error?: Error; value?: T }

export function createPromiseCallback<
V,
CALLBACK extends (...args: any[]) => { value?: V; error?: Error } | void,
R = ReturnType<CALLBACK>
>(
callback: CALLBACK
export function createPromiseCallback<CALLBACK extends (...args: any[]) => Error | void>(
callback: CALLBACK,
stopOnError: boolean = true
): {
promise: Promise<InferPromiseResult<CALLBACK>>
promise: Promise<void>
callback: CALLBACK
resolved: Ref<boolean>
error: Ref<Error | undefined>
} {
const errorRef = ref<Error>()
let result: Result<V>
let result: Error | true
const resolvedRef = ref(false)
let resolveEffect: Function = () => {}
const proxyResolve = new Proxy(callback, {
apply: function (target: CALLBACK, _thisArg: any, argumentsList: any[]) {
let r = target(...argumentsList)
result = r as R & { success: boolean }
if (r === undefined || Object.keys(r).length === 0) {
result = { success: true } as R & { success: boolean }
} else if (r.error) {
errorRef.value = r.error
result.success = false
} else if (r.value) {
result.success = true
}
if (result.success) {
if (r instanceof Error) {
errorRef.value = r
result = r
} else {
resolvedRef.value = true
errorRef.value = undefined
result = true
}
resolveEffect(result)
return result
resolveEffect()
},
}) as CALLBACK
const promise = new Promise<InferPromiseResult<CALLBACK>>((res, rej) => {
if (resolvedRef.value) {
res(result as InferPromiseResult<CALLBACK>)
const promise = new Promise<void>((res, rej) => {
if (stopOnError && result instanceof Error) {
rej(result)
return
} else if (errorRef.value) {
rej(errorRef.value)
} else if (result === true) {
res()
return
}
resolveEffect = () => {
if (resolvedRef.value) {
res(result as InferPromiseResult<CALLBACK>)
if (stopOnError && result instanceof Error) {
rej(result)
return
} else if (errorRef.value) {
rej(errorRef.value)
} else if (result === true) {
res()
return
}
}
Expand Down
7 changes: 4 additions & 3 deletions libs/domain-server/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { createPromiseCallback } from './common'

export type DomainEventData = { [key: string]: any }

export type DomainRequestEventCallback = <T>(...args: any[]) => { value?: T; error?: Error } | void
export type DomainRequestEventCallback = (...args: any[]) => void | Error

export type DomainEvent<DATA extends DomainEventData, CALLBACK extends DomainRequestEventCallback> =
| DomainRequestEvent<DATA, CALLBACK>
Expand All @@ -29,7 +29,8 @@ export type DomainBroadcastEvent<DATA extends DomainEventData> = ReturnType<type

export function createRequestEvent<DATA extends DomainEventData, REPLY extends DomainRequestEventCallback>(
_: DATA,
reply: REPLY
reply: REPLY,
stopOnError = true
) {
let version = shallowRef('0')
const map: Record<
Expand Down Expand Up @@ -88,7 +89,7 @@ export function createRequestEvent<DATA extends DomainEventData, REPLY extends D
}

const publishFn = async (data: UnwrapNestedRefs<DATA>) => {
const { promise, callback: res, resolved, error } = createPromiseCallback(reply)
const { promise, callback: res, resolved, error } = createPromiseCallback(reply, stopOnError)
updateEvent(data, res, resolved, error)
await promise
}
Expand Down
10 changes: 7 additions & 3 deletions libs/domain/__tests__/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ import { expect, it } from '@jest/globals'
import { Utils } from '..'

it('createPromiseCallback 成功', async () => {
const { promise, resolved, callback, error } = Utils.createPromiseCallback(() => {})
const { promise, resolved, callback, error } = Utils.createPromiseCallback(() => {
const a = true
if (!a) {
return new Error('error')
}
})
callback()
const result = await promise
await promise
expect(resolved.value).toBe(true)
expect(error.value).toBe(undefined)
expect(result.success).toBe(true)
})
58 changes: 43 additions & 15 deletions libs/domain/__tests__/event.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { it, expect } from '@jest/globals'
import { createBroadcastEvent, createRequestEvent } from '../event'
import { ref, reactive } from 'vue'
import { ref } from 'vue'

it('createChannelEvent 触发事件', async () => {
function register() {
Expand Down Expand Up @@ -46,40 +46,68 @@ it('createChannelEvent 函数的回调', async () => {
})

it('createChannelEvent Promise的回调', async () => {
const listenerCounter = reactive<string[]>([])
const listenerCounter = ref(0)
let succeed = false
function createInitEvent() {
const event = createRequestEvent({}, (name: string) => {
if (name !== 'Andy') {
return new Error('incorrect name')
}
listenerCounter.value++
succeed = true
})
return event
}
const watchedEventsCounter = ref(0)
const initEvent = createInitEvent()
initEvent.toApi().watchPublishRequest(({ reply }) => {
watchedEventsCounter.value++
reply('Andy')
})
initEvent.toApi().watchPublishRequest(({ reply }) => {
watchedEventsCounter.value++
reply('Andy')
})
await initEvent.publishRequest({ name: 'Andy' })
expect(succeed).toBe(true)
expect(listenerCounter.value).toBe(1)
expect(watchedEventsCounter.value).toBe(1)
})

it('createChannelEvent Promise的回调', async () => {
const listenerCounter = ref(0)
let succeed = false
function createInitEvent() {
const name = ref('wong')
const event = createRequestEvent({ name }, (b: boolean) => {
listenerCounter.push('')
succeed = b
const start = Date.now()
while (Date.now() - start < 10) {
// 运行10ms
const event = createRequestEvent({ name }, (name: string) => {
if (name !== 'Andy') {
return new Error('incorrect name')
}
listenerCounter.value++
succeed = true
})
return event
}
const watchedEventsCounter = reactive<string[]>([])
const watchedEventsCounter = ref(0)
const initEvent = createInitEvent()
initEvent.toApi().watchPublishRequest(({ data, reply }) => {
watchedEventsCounter.push('')
watchedEventsCounter.value++
if (data.name === 'Andy') {
succeed = true
}
reply(true)
reply('Andy')
})
initEvent.toApi().watchPublishRequest(({ data, reply }) => {
watchedEventsCounter.push('')
watchedEventsCounter.value++
if (data.name === 'Andy') {
succeed = true
}
reply(true)
reply('Andy')
})
await initEvent.publishRequest({ name: 'Andy' })
expect(succeed).toBe(true)
expect(listenerCounter.length).toBe(1)
expect(watchedEventsCounter.length).toBe(1)
expect(listenerCounter.value).toBe(1)
expect(watchedEventsCounter.value).toBe(1)
})

it('createBroadcastEvent Promise的回调', async () => {
Expand Down
6 changes: 3 additions & 3 deletions libs/domain/agg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
DomainEvent,
DomainRequestEvent,
} from './event'
import { type Result, createPromiseCallback } from './common'
import { createPromiseCallback } from './common'

type AddDestroyedEvent<T extends object, K = 'destroyed'> = keyof T extends never
? { destroyed: DomainBroadcastEvent<{}> }
Expand Down Expand Up @@ -189,7 +189,7 @@ export function createUnmountableAgg<
onCreated: (fn: () => void) => void
onBeforeInitialize: (fn: () => void) => void
initialized: ComputedRef<boolean>
untilInitialized: Promise<Result<undefined>>
untilInitialized: Promise<void>
}) => {
states?: STATES
actions?: ACTIONS
Expand Down Expand Up @@ -265,7 +265,7 @@ export function createAgg<
onCreated: (fn: () => void) => void
onBeforeInitialize: (fn: () => void) => void
initialized: ComputedRef<boolean>
untilInitialized: Promise<Result<undefined>>
untilInitialized: Promise<void>
}) => {
states?: STATES
actions?: ACTIONS
Expand Down
Loading

0 comments on commit db5d4f4

Please sign in to comment.