1
1
import { type DurableObjectState , type ExecutionContext } from '@cloudflare/workers-types' ;
2
2
3
3
type ContextType = ExecutionContext | DurableObjectState ;
4
- type OverridesStore = Map < string | symbol , ( ...args : unknown [ ] ) => unknown > ;
4
+ type OverridesStore < T extends ContextType > = Map < keyof T , ( ...args : unknown [ ] ) => unknown > ;
5
5
6
6
/**
7
7
* Creates a new copy of the given execution context, optionally overriding methods.
@@ -12,34 +12,43 @@ type OverridesStore = Map<string | symbol, (...args: unknown[]) => unknown>;
12
12
export function copyExecutionContext < T extends ContextType > ( ctx : T ) : T {
13
13
if ( ! ctx ) return ctx ;
14
14
15
- const overrides : OverridesStore = new Map ( ) ;
15
+ const overrides : OverridesStore < T > = new Map ( ) ;
16
16
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 ) => {
18
19
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 ) ;
20
22
return {
21
23
...prevDescriptors ,
22
- [ methodName ] : pd ,
24
+ [ methodName ] : overridableDescriptor ,
23
25
} ;
24
26
} , { } ) ;
25
27
26
28
return Object . create ( ctx , descriptors ) ;
27
29
}
28
30
29
31
/**
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 .
31
33
*
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.
36
41
*/
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 {
38
47
return {
39
48
configurable : true ,
40
49
enumerable : true ,
41
50
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' ) ;
43
52
store . set ( method , newValue ) ;
44
53
return true ;
45
54
} ,
0 commit comments