import { decoratorWithParams , DecoratorDescriptor } from '@ember-decorators/utils/decorator' ; import { assert } from '@ember/debug' ; import { task as createTaskProperty , taskGroup as createTaskGroupProperty , TaskFunction as GenericTaskFunction , TaskProperty as GenericTaskProperty , TaskGroupProperty as GenericTaskGroupProperty , EncapsulatedTaskDescriptor as GenericEncapsulatedTask } from 'ember-concurrency' ; export { default as lastValue } from './last-value' ; type TaskFunction = GenericTaskFunction < unknown , unknown [ ] > ; type TaskProperty = GenericTaskProperty < unknown , unknown [ ] > ; type TaskGroupProperty = GenericTaskGroupProperty < unknown > ; type EncapsulatedTask = GenericEncapsulatedTask < unknown , unknown [ ] > ; type OptionsFor < T extends object > = { [ K in OptionKeysFor < T > ] ? : OptionTypeFor < T , T [ K ] > ; } ; type OptionKeysFor < T extends object > = { [ K in keyof T ] : OptionKeyFor < T , K , T [ K ] > ; } [ keyof T ] ; type OptionKeyFor < T , K , F > = F extends ( ... args : any [ ] ) => T ? K : never ; type OptionTypeFor < T , F > = F extends ( ... args : infer Args ) => T ? Args [ 0 ] extends undefined ? true : Args [ 0 ] : never ; type TaskOptions = OptionsFor < TaskProperty > ; type TaskGroupOptions = OptionsFor < TaskGroupProperty > ; type Decorator = ( ... args : Parameters < MethodDecorator > ) => Exclude < ReturnType < MethodDecorator > , void > ; type ObjectValues < O > = O extends { [ s ] : infer V ; } ? V : never ; task task param desc returns { object | null } private function extractValue ( desc ) { if ( typeof desc . initializer === 'function' ) { return desc . initializer . call ( undefined ) ; } if ( typeof desc . get === 'function' ) { return desc . get . call ( undefined ) ; } if ( desc . value ) { return desc . value ; } return undefined ; } function isTaskFunction ( value ) { return typeof value === 'function' ; } function isEncapsulatedTask ( value ) { return ( typeof value === 'object' && value !== null && isTaskFunction ( ( value as { perform ? : unknown ; } ) . perform ) ) ; } param desc returns { TaskProperty } private function createTaskFromDescriptor ( desc ) { const value = extractValue ( desc ) ; if ( isTaskFunction ( value ) ) { return createTaskProperty ( value ) ; } if ( isEncapsulatedTask ( value ) ) { return createTaskProperty ( value ) ; } assert ( 'ember-concurrency-decorators: Can only decorate a generator function as a task or an object with a generator method `perform` as an encapsulated task.' ) ; } param desc returns { TaskGroupProperty } private function createTaskGroupFromDescriptor ( _desc ) { return createTaskGroupProperty ( ) ; } param options param { TaskProperty | TaskGroupProperty } task private function applyOptions ( options , task ) ; function applyOptions ( options , task ) ; function applyOptions ( options , task ) { const keys = Object . keys ( options ) as Array < keyof typeof options > ; for ( const key of keys ) { const value = options [ key ] ; assert ( `ember-concurrency-decorators: Option '${ key }' is not a valid value` , value !== undefined ) ; assert ( `ember-concurrency-decorators: Option '${ key }' is not a valid function` , typeof task [ key ] === 'function' ) ; if ( value === true ) { ( task [ key ] as ( ) => typeof task ) ( ) ; } else { ( task [ key ] as ( o : typeof value ) => typeof task ) ( value ) ; } } return task as typeof task & Decorator ; } type MethodOrPropertyDecoratorWithParams < Params extends unknown [ ] > = MethodDecorator & PropertyDecorator & ( ( ... params : Params ) => MethodDecorator & PropertyDecorator ) ; param { function } propertyCreator param { object } baseOptions private function createDecorator ( propertyCreator , baseOptions ? ) ; function createDecorator < Params extends unknown [ ] > ( propertyCreator , baseOptions ? ) ; function createDecorator ( propertyCreator , baseOptions = { } ) { return decoratorWithParams < object , [ typeof baseOptions ? ] > ( ( target , key , desc , [ userOptions ] = [ ] ) => { const { initializer , value } = desc ; delete desc . initializer ; delete desc . value ; return applyOptions ( { ... baseOptions , ... userOptions } , propertyCreator ( { ... desc , initializer , value } ) ) ( target , key , desc ) ; } ) ; } task task function param { object ? } options return { TaskProperty } export const task = createDecorator ( createTaskFromDescriptor ) ; function param { object ? } options return { TaskProperty } export const restartableTask = createDecorator ( createTaskFromDescriptor , { restartable : true } ) ; function param { object ? } options return { TaskProperty } export const dropTask = createDecorator ( createTaskFromDescriptor , { drop : true } ) ; function param { object ? } options return { TaskProperty } export const keepLatestTask = createDecorator ( createTaskFromDescriptor , { keepLatest : true } ) ; function param { object ? } options return { TaskProperty } export const enqueueTask = createDecorator ( createTaskFromDescriptor , { enqueue : true } ) ; taskGroup task task function param { object ? } options return { TaskGroupProperty } export const taskGroup = createDecorator ( createTaskGroupFromDescriptor ) ; function param { object ? } options return { TaskGroupProperty } export const restartableTaskGroup = createDecorator ( createTaskGroupFromDescriptor , { restartable : true } ) ; function param { object ? } options return { TaskGroupProperty } export const dropTaskGroup = createDecorator ( createTaskGroupFromDescriptor , { drop : true } ) ; function param { object ? } options return { TaskGroupProperty } export const keepLatestTaskGroup = createDecorator ( createTaskGroupFromDescriptor , { keepLatest : true } ) ; function param { object ? } options return { TaskGroupProperty } export const enqueueTaskGroup = createDecorator ( createTaskGroupFromDescriptor , { enqueue : true } ) ;