|
|
|
@ -1,5 +1,5 @@
|
|
|
|
|
import {Container, Inject, Injectable, Instantiable} from '../../di'
|
|
|
|
|
import {Awaitable, ErrorWithContext, JSONState, uuid4} from '../../util'
|
|
|
|
|
import {Awaitable, ErrorWithContext, hasOwnProperty, JSONState, uuid4} from '../../util'
|
|
|
|
|
import {BaseSerializer} from './serial/BaseSerializer'
|
|
|
|
|
import {Event} from './types'
|
|
|
|
|
|
|
|
|
@ -59,6 +59,21 @@ export abstract class StateEvent<T extends JSONState> implements Event {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** A serialized `StateEvent` instance. */
|
|
|
|
|
export type SerializedStateEvent<T extends JSONState = JSONState> = {
|
|
|
|
|
state: T,
|
|
|
|
|
eventUuid: string,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function isSerializedStateEvent(what: unknown): what is SerializedStateEvent {
|
|
|
|
|
return (
|
|
|
|
|
typeof what === 'object' && what !== null
|
|
|
|
|
&& hasOwnProperty(what, 'state')
|
|
|
|
|
&& hasOwnProperty(what, 'eventUuid')
|
|
|
|
|
&& typeof what.eventUuid === 'string'
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Generic serializer implementation for StateEvents.
|
|
|
|
|
* Note that this is NOT registered with @ObjectSerializer() because we need to
|
|
|
|
@ -80,7 +95,7 @@ export abstract class StateEvent<T extends JSONState> implements Event {
|
|
|
|
|
* ```
|
|
|
|
|
*/
|
|
|
|
|
@Injectable()
|
|
|
|
|
export class StateEventSerializer extends BaseSerializer<StateEvent<JSONState>, JSONState> {
|
|
|
|
|
export class StateEventSerializer extends BaseSerializer<StateEvent<JSONState>, SerializedStateEvent> {
|
|
|
|
|
@Inject()
|
|
|
|
|
protected readonly injector!: Container
|
|
|
|
|
|
|
|
|
@ -98,20 +113,24 @@ export class StateEventSerializer extends BaseSerializer<StateEvent<JSONState>,
|
|
|
|
|
return some instanceof this.eventClass
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected encodeActual(actual: StateEvent<JSONState>): Awaitable<JSONState> {
|
|
|
|
|
return actual.getState()
|
|
|
|
|
protected encodeActual(actual: StateEvent<JSONState>): Awaitable<SerializedStateEvent> {
|
|
|
|
|
return {
|
|
|
|
|
state: actual.getState(),
|
|
|
|
|
eventUuid: actual.eventUuid,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected decodeSerial(serial: JSONState): Awaitable<StateEvent<JSONState>> {
|
|
|
|
|
protected decodeSerial(serial: SerializedStateEvent): Awaitable<StateEvent<JSONState>> {
|
|
|
|
|
const inst = this.injector.makeNew<StateEvent<JSONState>>(this.eventClass)
|
|
|
|
|
if ( !inst.validate(serial) ) {
|
|
|
|
|
if ( !isSerializedStateEvent(serial) || !inst.validate(serial.state) ) {
|
|
|
|
|
throw new ErrorWithContext('Invalid serial state', {
|
|
|
|
|
serial,
|
|
|
|
|
eventClass: inst.getName(),
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inst.setState(serial)
|
|
|
|
|
inst.setState(serial.state)
|
|
|
|
|
inst.eventUuid = serial.eventUuid
|
|
|
|
|
return inst
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|