Skip to content

Commit

Permalink
Port the FastTransformer class
Browse files Browse the repository at this point in the history
  • Loading branch information
cedx committed Nov 4, 2024
1 parent fa341ac commit 521d013
Show file tree
Hide file tree
Showing 17 changed files with 120 additions and 190 deletions.
2 changes: 1 addition & 1 deletion example/gulpfile.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ export compressPhp = ->
mode: if isWindows then "safe" else "fast"
silent: process.stdout.isTTY

return gulp.src "path/to/**/*.php", read: false
gulp.src "path/to/**/*.php", read: false
.pipe phpMinify options
.pipe gulp.dest "path/to/out"
26 changes: 26 additions & 0 deletions lib/fast_transformer.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {Transformer} from "./transformer.js";

/**
* Removes comments and whitespace from a PHP script, by calling a Web service.
*/
export class FastTransformer implements Transformer {

/**
* Creates a new fast transformer.
* @param executable The path to the PHP executable.
*/
constructor(executable?: string);

/**
* Closes this transformer and releases any resources associated with it.
* @returns Resolves when the transformer is finally disposed.
*/
close(): Promise<void>;

/**
* Processes a PHP script.
* @param file The path to the PHP script.
* @returns The transformed script.
*/
transform(file: string): Promise<string>;
}
1 change: 1 addition & 0 deletions lib/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {Transform} from "node:stream";
export * from "./fast_transformer.js";
export * from "./safe_transformer.js";
export * from "./transformer.js";

Expand Down
5 changes: 0 additions & 5 deletions lib/safe_transformer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@ import {Transformer} from "./transformer.js";
*/
export class SafeTransformer implements Transformer {

/**
* The path to the PHP executable.
*/
executable: string;

/**
* Creates a new safe transformer.
* @param executable The path to the PHP executable.
Expand Down
Empty file added src/cli.coffee
Empty file.
52 changes: 52 additions & 0 deletions src/fast_transformer.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {spawn} from "node:child_process"
import {createServer} from "node:net"
import {join, normalize, resolve} from "node:path"
import {setTimeout} from "node:timers"

# Removes comments and whitespace from a PHP script, by calling a Web service.
export class FastTransformer

# Creates a new fast transformer.
constructor: (executable = "php") ->

# The path to the PHP executable.
@_executable = normalize executable

# The port that the PHP process is listening on.
@_port = -1

# The underlying PHP process.
@_process = null

# Closes this transformer and releases any resources associated with it.
close: ->
@_process?.kill()
@_process = null
Promise.resolve()

# Starts the underlying PHP process and begins accepting connections.
listen: -> if @_process? then Promise.resolve @_port else
@_port = await @_getPort()
args = ["-S", "127.0.0.1:#{@_port}", "-t", join(import.meta.dirname, "../www")]
new Promise (fulfill, reject) =>
spawn @_executable, args, stdio: ["ignore", "pipe", "ignore"]
.on "error", reject
.on "spawn", => setTimeout (=> fulfill @_port), 1000

# Processes a PHP script.
transform: (file) ->
await @listen()
url = new URL "http://127.0.0.1:#{@_port}/index.php"
url.searchParams.set "file", resolve(file)

response = await fetch url
throw Error("An error occurred while processing the script: #{file}") unless response.ok
response.text()

# Gets an ephemeral TCP port chosen by the system.
_getPort: -> new Promise (fulfill, reject) ->
socket = createServer().on "error", reject
socket.unref()
socket.listen host: "127.0.0.1", port: 0, ->
{port} = socket.address()
socket.close -> fulfill port
Empty file added src/gulp_plugin.coffee
Empty file.
1 change: 1 addition & 0 deletions src/index.coffee
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./fast_transformer.js"
export * from "./safe_transformer.js"
69 changes: 0 additions & 69 deletions src/php_minifier/FastTransformer.hx

This file was deleted.

27 changes: 0 additions & 27 deletions src/php_minifier/SafeTransformer.hx

This file was deleted.

11 changes: 0 additions & 11 deletions src/php_minifier/Transformer.hx

This file was deleted.

4 changes: 2 additions & 2 deletions src/safe_transformer.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ export class SafeTransformer
constructor: (executable = "php") ->

# The path to the PHP executable.
@executable = normalize executable
@_executable = normalize executable

# Closes this transformer and releases any resources associated with it.
close: -> Promise.resolve()

# Processes a PHP script.
transform: (file) -> (await run @executable, ["-w", resolve file], maxBuffer: 20 * 1024 * 1024).stdout
transform: (file) -> (await run @_executable, ["-w", resolve file], maxBuffer: 20 * 1024 * 1024).stdout
34 changes: 34 additions & 0 deletions test/fast_transformer_test.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {FastTransformer} from "@cedx/php-minifier"
import {doesNotReject, ok} from "node:assert/strict"
import {after, describe, it} from "node:test"

# Tests the features of the `FastTransformer` class.
describe "FastTransformer", ->
describe "close()", ->
it "should not reject, even if called several times", ->
transformer = new FastTransformer
await doesNotReject transformer.listen()
await doesNotReject transformer.close()
await doesNotReject transformer.close()

describe "listen()", ->
it "should not reject, even if called several times", ->
transformer = new FastTransformer
await doesNotReject transformer.listen()
await doesNotReject transformer.listen()
await doesNotReject transformer.close()

describe "transform()", ->
map = new Map [
["should remove the inline comments", "<?= 'Hello World!' ?>"]
["should remove the multi-line comments", "namespace dummy; class Dummy"]
["should remove the single-line comments", "$className = get_class($this); return $className;"]
["should remove the whitespace", "__construct() { $this->property"]
]

transformer = new FastTransformer
after -> transformer.close()

for [key, value] from map then it key, ->
output = await transformer.transform "res/sample.php"
ok output.includes value
Empty file added test/gulp_plugin_test.coffee
Empty file.
40 changes: 0 additions & 40 deletions test/php_minifier/FastTransformerTest.hx

This file was deleted.

31 changes: 0 additions & 31 deletions test/php_minifier/SafeTransformerTest.hx

This file was deleted.

7 changes: 3 additions & 4 deletions test/safe_transformer_test.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,16 @@ describe "SafeTransformer", ->
await doesNotReject transformer.close()

describe "transform()", ->
map = new Map([
map = new Map [
["should remove the inline comments", "<?= 'Hello World!' ?>"]
["should remove the multi-line comments", "namespace dummy; class Dummy"]
["should remove the single-line comments", "$className = get_class($this); return $className;"]
["should remove the whitespace", "__construct() { $this->property"]
])
]

script = "res/sample.php"
transformer = new SafeTransformer
after -> transformer.close()

for [key, value] from map then it key, ->
output = await transformer.transform script
output = await transformer.transform "res/sample.php"
ok output.includes value

0 comments on commit 521d013

Please sign in to comment.