@@ -7,7 +7,7 @@ import { dependenciesTotalSize, init } from "../../../node_modules/@php-wasm/web
77import phpWasmModule from "../../../node_modules/@php-wasm/web-8-5/asyncify/8_5_8/php_8_5.wasm"
88import { CLOUDFLARE_RUNTIME_HEALTH_MARKER , CLOUDFLARE_RUNTIME_HEALTH_SCHEMA , cloudflareRuntimeHealthResponse } from "./health-envelope.js"
99import { leaseRetryDelayMs } from "./lease-retry.js"
10- import { routeWorkerRequest } from "./request-routing.js"
10+ import { routeWorkerRequest , type EditorProbePhase } from "./request-routing.js"
1111import { toFetchResponse , toPHPRequest } from "./request-translation.js"
1212import { deriveWordPressAuthConstants , type WordPressAuthConstant } from "./wordpress-auth.js"
1313import { isWordPressRuntimeFile , wordpressStaticArchivePath , wordpressStaticContentType } from "./wordpress-runtime-corpus.js"
@@ -86,6 +86,7 @@ export default {
8686 const route = routeWorkerRequest ( request )
8787 const coordinator = env . WORDPRESS_STATE . getByName ( "default" )
8888 if ( route . kind === "operator-reset" ) return resetCanonicalWordPress ( request , env , coordinator )
89+ if ( route . kind === "editor-probe" ) return runCoordinatedEditorProbe ( request , env , coordinator , route . phase )
8990 if ( route . kind === "probe" ) {
9091 if ( route . phase === "canonical-session" ) return canonicalSessionProbe ( env . WORDPRESS_STATE_BUCKET , await coordinatorCall < { pointer : MarkdownPointer | null } > ( coordinator , request . url , "state" ) )
9192 return runBootProbe ( route . phase , env . WORDPRESS_STATE_BUCKET )
@@ -99,6 +100,41 @@ export default {
99100 } ,
100101}
101102
103+ async function runCoordinatedEditorProbe ( request : Request , env : Env , coordinator : DurableObjectStub , phase : EditorProbePhase ) : Promise < Response > {
104+ const lease = await acquireLease ( coordinator , request . url )
105+ let finalized = false
106+ try {
107+ if ( ! lease . pointer ) throw new Error ( "Canonical WordPress must be initialized before running an editor probe." )
108+ const runtime = await getRuntime ( env , lease . pointer , new URL ( request . url ) . origin )
109+ patchEditorProbe ( runtime . php , phase )
110+ const response = toFetchResponse ( request , await runtime . requestHandler . request ( await toPHPRequest ( request ) ) )
111+ await releaseLease ( coordinator , request . url , lease )
112+ finalized = true
113+ await discardCachedRuntime ( )
114+ return response
115+ } catch ( error ) {
116+ if ( ! finalized ) await abortLease ( coordinator , request . url , lease )
117+ await discardCachedRuntime ( )
118+ throw error
119+ }
120+ }
121+
122+ function patchEditorProbe ( php : PHP , phase : EditorProbePhase ) : void {
123+ const path = "/wordpress/wp-admin/post-new.php"
124+ const source = new TextDecoder ( ) . decode ( php . readFileAsBuffer ( path ) )
125+ const markers : Record < EditorProbePhase , string > = {
126+ admin : "require_once __DIR__ . '/admin.php';" ,
127+ "auto-draft" : "$post_ID = $post->ID;" ,
128+ "block-editor" : "require_once ABSPATH . 'wp-admin/admin-footer.php';" ,
129+ }
130+ const marker = markers [ phase ]
131+ const index = source . indexOf ( marker )
132+ if ( index === - 1 || index !== source . lastIndexOf ( marker ) ) throw new Error ( `WordPress editor probe marker is not unique: ${ phase } ` )
133+ const stop = `\necho wp_json_encode( array( 'schema' => 'wp-codebox/cloudflare-editor-probe/v1', 'phase' => '${ phase } ', 'memoryBytes' => memory_get_usage( true ), 'peakMemoryBytes' => memory_get_peak_usage( true ) ) );\nreturn;`
134+ const insertion = phase === "block-editor" ? index : index + marker . length
135+ php . writeFile ( path , new TextEncoder ( ) . encode ( `${ source . slice ( 0 , insertion ) } ${ stop } ${ source . slice ( insertion ) } ` ) )
136+ }
137+
102138interface MarkdownManifestFile {
103139 path : string
104140 objectKey : string
0 commit comments