11import { type DurableObjectState , type ExecutionContext } from '@cloudflare/workers-types' ;
22
33type ContextType = ExecutionContext | DurableObjectState ;
4- type OverridesStore = Map < string | symbol , ( ...args : unknown [ ] ) => unknown > ;
4+ type OverridesStore < T extends ContextType > = Map < keyof T , ( ...args : unknown [ ] ) => unknown > ;
55
66/**
77 * Creates a new copy of the given execution context, optionally overriding methods.
@@ -12,34 +12,43 @@ type OverridesStore = Map<string | symbol, (...args: unknown[]) => unknown>;
1212export function copyExecutionContext < T extends ContextType > ( ctx : T ) : T {
1313 if ( ! ctx ) return ctx ;
1414
15- const overrides : OverridesStore = new Map ( ) ;
15+ const overrides : OverridesStore < T > = new Map ( ) ;
1616 const contextPrototype = Object . getPrototypeOf ( ctx ) ;
17- const descriptors = Object . getOwnPropertyNames ( contextPrototype ) . reduce ( ( prevDescriptors , methodName ) => {
17+ const methodNames = Object . getOwnPropertyNames ( contextPrototype ) as unknown as ( keyof T ) [ ] ;
18+ const descriptors = methodNames . reduce ( ( prevDescriptors , methodName ) => {
1819 if ( methodName === 'constructor' ) return prevDescriptors ;
19- const pd = makeMethodDescriptor ( overrides , ctx , methodName as keyof ContextType ) ;
20+ if ( typeof ctx [ methodName ] !== 'function' ) return prevDescriptors ;
21+ const overridableDescriptor = makeOverridableDescriptor ( overrides , ctx , methodName ) ;
2022 return {
2123 ...prevDescriptors ,
22- [ methodName ] : pd ,
24+ [ methodName ] : overridableDescriptor ,
2325 } ;
2426 } , { } ) ;
2527
2628 return Object . create ( ctx , descriptors ) ;
2729}
2830
2931/**
30- * Creates a property descriptor for a given method on a context object, enabling custom getter and setter behavior .
32+ * Creates a property descriptor that allows overriding of a method on the given context object .
3133 *
32- * @param store - The OverridesStore instance used to manage method overrides.
33- * @param ctx - The context object from which the method originates.
34- * @param method - The key of the method on the context object to create a descriptor for.
35- * @return A property descriptor with custom getter and setter functionalities for the specified method.
34+ * This descriptor supports property overriding with functions only. It delegates method calls to
35+ * the provided store if an override exists or to the original method on the context otherwise.
36+ *
37+ * @param {OverridesStore<ContextType> } store - The storage for overridden methods specific to the context type.
38+ * @param {ContextType } ctx - The context object that contains the method to be overridden.
39+ * @param {keyof ContextType } method - The method on the context object to create the overridable descriptor for.
40+ * @return {PropertyDescriptor } A property descriptor enabling the overriding of the specified method.
3641 */
37- function makeMethodDescriptor ( store : OverridesStore , ctx : ContextType , method : keyof ContextType ) : PropertyDescriptor {
42+ function makeOverridableDescriptor < T extends ContextType > (
43+ store : OverridesStore < T > ,
44+ ctx : T ,
45+ method : keyof T ,
46+ ) : PropertyDescriptor {
3847 return {
3948 configurable : true ,
4049 enumerable : true ,
4150 set : newValue => {
42- if ( typeof newValue !== 'function' ) throw new Error ( 'Cannot override non-function' )
51+ if ( typeof newValue !== 'function' ) throw new Error ( 'Cannot override non-function' ) ;
4352 store . set ( method , newValue ) ;
4453 return true ;
4554 } ,
0 commit comments