Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
4b7dacf
Explore unzipping files using DecompressionStream instead of passing …
adamziel Dec 9, 2023
b776c7b
Remove custom importing logic, use Blueprint steps instead
adamziel Dec 9, 2023
17f4bb4
Scanning remote zip file
adamziel Dec 11, 2023
3e21b3c
Working zip scanning through repeated fetch() calls!
adamziel Dec 11, 2023
c2abb74
Fast chunked download
adamziel Dec 11, 2023
035b3f1
Simplify
adamziel Dec 11, 2023
92c4ad0
Explore stream concatenation
adamziel Dec 11, 2023
019ff4e
Use makeReadableByteStream
adamziel Dec 11, 2023
1646ef6
Move more towards streams
adamziel Dec 12, 2023
27bfce3
Read central directory headers in one go
adamziel Dec 12, 2023
a382076
API Cleanup
adamziel Dec 12, 2023
5fa7b47
Experiment: listZipFiles returns a stream
adamziel Dec 12, 2023
bbac923
Getting somewhere with the API shape
adamziel Dec 12, 2023
9eee842
Embrace streams for partitioning and fetching the partitioned data
adamziel Dec 12, 2023
c05a0bf
Precompute lastByteAt
adamziel Dec 12, 2023
53826ee
Save one fetch() request by reusing the bytes downloaded to find the …
adamziel Dec 12, 2023
afb62d3
Scan for the signature from the end to the start
adamziel Dec 12, 2023
de89933
Tidied up API
adamziel Dec 12, 2023
2f8838e
Implement iterateFromUrl
adamziel Dec 12, 2023
ca16410
Clean up types
adamziel Dec 12, 2023
2e4f891
Download 110KB when scanning the directory index
adamziel Dec 12, 2023
ff59b06
Clean up
adamziel Dec 12, 2023
37aab97
Don't do ranges if the no predicate is specified
adamziel Dec 13, 2023
4045568
Check for ranges query support
adamziel Dec 13, 2023
42850a4
Confirm ranges work and reuse the response stream if they don't
adamziel Dec 13, 2023
8edcc06
Cleanup the code
adamziel Dec 13, 2023
6980d21
Split into separate files
adamziel Dec 13, 2023
b049d62
Update 01-index.md
adamziel Dec 13, 2023
f4fd9cd
Support compressing files
adamziel Dec 14, 2023
27f1c24
Use Uint8Arrays to represent strings internally
adamziel Dec 14, 2023
2035e3c
Code style
adamziel Dec 14, 2023
b8c9e1c
Move common functions to utils folder
adamziel Dec 14, 2023
6ddc393
Remove PHP zipping logic
adamziel Dec 14, 2023
52885ae
Remove readAllBytes helper
adamziel Dec 14, 2023
234e161
Harmonize the API
adamziel Dec 14, 2023
51bfe5b
Refactor the changeset function to handle two iterables
adamziel Dec 14, 2023
a358100
Replace FileEntry with File
adamziel Dec 14, 2023
8a7274c
Remove the text() property from ZipFileEntry
adamziel Dec 14, 2023
9c9d257
Document helper methods
adamziel Dec 14, 2023
6f0e3bf
Move streaming function to their own package (@wp-playground/stream-c…
adamziel Dec 15, 2023
eb42147
Cleanup the API
adamziel Dec 15, 2023
4c11253
Add comments and inline documentation
adamziel Dec 15, 2023
726fc68
Clean up the API
adamziel Dec 15, 2023
052d0fb
Merge branch 'trunk' into explore-decompression-streams-and-iterators
adamziel Dec 15, 2023
0386863
Add basic unit tests
adamziel Dec 15, 2023
96cf31f
Fix a typo
adamziel Dec 15, 2023
8bdea1f
Remove the dependency check eslint rule
adamziel Dec 16, 2023
93ac815
Adjust stream-compression/package.json
adamziel Dec 16, 2023
b2e4fbd
Polyfill CustomEvent and Blob methods for Node.js
adamziel Dec 16, 2023
dad4b8d
Polyfill deflate-raw compression method using the gzip compression me…
adamziel Dec 17, 2023
a8ed4c0
Lint
adamziel Dec 17, 2023
2bf3e1f
Fix Blueprints export
adamziel Dec 17, 2023
481e44a
Restore the correct repo name
adamziel Dec 17, 2023
dc37c01
Fix dev artifacts in Blob polyfills
adamziel Dec 17, 2023
00e3de9
Adjust unit tests
adamziel Dec 17, 2023
21c025c
ADd vitest setups
adamziel Dec 17, 2023
6b8aee3
Restore trunk's dependencies
Dec 17, 2023
345eced
Fix the error where vitest cannot find php-wasm/node-polyfills
Dec 17, 2023
6b3924c
General cleanup
Dec 17, 2023
e7dc0af
Restore BYOB stream polyifll
Dec 17, 2023
0046aef
Fix isByobSupported() check
Dec 17, 2023
ca9e681
Fix ESMCJS check in GitHub CI
Dec 17, 2023
46c36eb
Handle invalid content-length values
Dec 17, 2023
2d31a1f
Remove esmcjs test from wp-playground/wordpress project.json
Dec 17, 2023
b35ffb3
Fix Blueprints unit tests
Dec 17, 2023
0719f67
Simplify Blueprints tests
Dec 17, 2023
a4df29f
Preserve the BYOB stream property when monitoring the download progress
adamziel Dec 18, 2023
919a17b
Adjust error messages in unit tests
adamziel Dec 18, 2023
3548789
Fix unit tests
adamziel Dec 18, 2023
0cd54f2
Wait a minute before failing the Gutenberg plugin installed E2E test
adamziel Dec 18, 2023
0d50cc7
Merge branch 'trunk' into explore-decompression-streams-and-iterators
adamziel Jan 8, 2024
3e2d4cd
Move the stream-compression logic to php-wasm
adamziel Jan 8, 2024
41cffb5
Clean up package-lock.json and remove unnecessary file-polyfill.ts
adamziel Jan 8, 2024
4d0a0e2
Merge branch 'trunk' into explore-decompression-streams-and-iterators
adamziel Jan 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ jobs:
- uses: actions/checkout@v3
- uses: ./.github/actions/prepare-playground
- run: npx nx affected --target=build --parallel=3 --verbose
# Make sure that both the ESM and CJS builds of the affected
# modules still produce usable bundles
- run: npx nx affected --target=test:esmcjs --parallel=3 --verbose

# Deploy documentation job
deploy_docs:
Expand Down
32 changes: 13 additions & 19 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Follow this checklist:
- Add a new `workspaces` in the top-level `package.json` file if needed. Otherwise TypeScript won't work correctly and Lerna won't pick up your package for publishing.
- Add a `typecheck` task to the `project.json` file in the new project. You can copy it from another project in this repo.
- Run `nx typecheck <project name>` to make sure TypeScript is set up correctly.
- If the project needs to ship both ESM and CJS builds, add a `test:esmcjs` task to the `project.json` and add it to the `dependsOn` list of the `test` task. This way the CI will continuously verify whether your double build works. The alternative is to find out when a disappointed extender files an issue.
- If the project needs to ship both ESM and CJS builds, add a `test:esmcjs` task to the `project.json`. This way the CI will continuously verify whether your double build works. The alternative is to find out when a disappointed extender files an issue.
- Add the `package-json` task to the build pipeline. See the details below.

### Package.json
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,16 @@ export default async function runExecutor(
const testsPath = path.join(context.root, buildDir, 'test-esm-cjs');
mkdirSync(testsPath, { recursive: true });

const testESMPath = path.join(testsPath, 'test-esm.mjs');
writeFileSync(
path.join(testsPath, 'test-esm.mjs'),
testESMPath,
`import * as result from '../../${options.outputPath}/index.js';`
);
writeFileSync(
path.join(testsPath, 'test-cjs.cjs'),
`require('../../${options.outputPath}');`
);
const checkForSuccess = (scriptName) =>
const testCJSPath = path.join(testsPath, 'test-cjs.cjs');
writeFileSync(testCJSPath, `require('../../${options.outputPath}');`);
const checkForSuccess = (scriptPath) =>
new Promise((resolve, reject) => {
const test = spawn('sh', ['node', scriptName], {
const test = spawn('node', [scriptPath], {
cwd: testsPath,
stdio: 'pipe',
});
Expand All @@ -49,7 +48,7 @@ export default async function runExecutor(
});
});

await checkForSuccess('test-esm.mjs');
await checkForSuccess('test-cjs.cjs');
await checkForSuccess(testESMPath);
await checkForSuccess(testCJSPath);
return { success: true };
}
83 changes: 52 additions & 31 deletions packages/php-wasm/progress/src/lib/emscripten-download-monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ export interface DownloadProgress {
total: number;
}

export function parseContentLength(contentLength: string | null) {
return parseInt(contentLength || '', 10) || FALLBACK_FILE_SIZE;
}

/**
* Clones a fetch Response object and returns a version
* that calls the `onProgress` callback as the #progress
Expand All @@ -186,8 +190,7 @@ export function cloneResponseMonitorProgress(
response: Response,
onProgress: (event: CustomEvent<DownloadProgress>) => void
): Response {
const contentLength = response.headers.get('content-length') || '';
const total = parseInt(contentLength, 10) || FALLBACK_FILE_SIZE;
const total = parseContentLength(response.headers.get('content-length'));

function notify(loaded: number, total: number) {
onProgress(
Expand All @@ -200,37 +203,19 @@ export function cloneResponseMonitorProgress(
);
}

// We could just tee() the response body here, but the following
// Chromium issue crashes the browser tab and prevents us from doing so:
// https://bugs.chromium.org/p/chromium/issues/detail?id=1512548
let seenBytes = 0;
return new Response(
new ReadableStream({
async start(controller) {
if (!response.body) {
controller.close();
return;
}
const reader = response.body.getReader();
let loaded = 0;
for (;;) {
try {
const { done, value } = await reader.read();
if (value) {
loaded += value.byteLength;
}
if (done) {
notify(loaded, loaded);
controller.close();
break;
} else {
notify(loaded, total);
controller.enqueue(value);
}
} catch (e) {
console.error({ e });
controller.error(e);
break;
}
}
peekByobStream(
response.body!,
(bytes) => {
seenBytes += bytes.byteLength;
notify(seenBytes, total);
},
}),
() => notify(total, total)
),
{
status: response.status,
statusText: response.statusText,
Expand All @@ -240,3 +225,39 @@ export function cloneResponseMonitorProgress(
}

export type DownloadProgressCallback = (progress: DownloadProgress) => void;

function peekByobStream(
stream: ReadableStream<Uint8Array>,
onChunk: (chunk: Uint8Array) => void,
onDone: () => void
) {
const reader = stream.getReader({ mode: 'byob' });
return new ReadableStream({
type: 'bytes',
// 0.5 MB seems like a reasonable chunk size, let's adjust
// this if needed.
autoAllocateChunkSize: 512 * 1024,

/**
* We could write directly to controller.byobRequest.view
* here. Unfortunately, in Chrome it detaches on the first
* `await` and cannot be reused once we actually have the data.
*/
async pull(controller) {
// Read the next chunk of data:
const view = controller.byobRequest!.view!;
const uint8array = new Uint8Array(view.byteLength);
const { value: chunk, done } = await reader.read(uint8array);
if (done) {
controller.close();
controller.byobRequest?.respond(0);
onDone();
return;
}

// Emit that chunk:
onChunk(chunk);
controller.byobRequest?.respondWithNewView(chunk);
},
});
}
2 changes: 1 addition & 1 deletion packages/php-wasm/scopes/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"types": "index.d.ts",
"gitHead": "2f8d8f3cea548fbd75111e8659a92f601cddc593",
"engines": {
"node": ">=16.15.1",
"node": ">=18.18.2",
"npm": ">=8.11.0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { UniversalPHP } from '@php-wasm/universal';
import { dirname, joinPaths } from '@php-wasm/util';

/**
* Writes streamed files to PHP filesystem.
*/
export function streamWriteToPhp(php: UniversalPHP, root: string) {
return new WritableStream({
async write(file: File) {
const filePath = joinPaths(root, file.name);
if (file.type === 'directory') {
await php.mkdir(filePath);
} else {
await php.mkdir(dirname(filePath));
await php.writeFile(
filePath,
new Uint8Array(await file.arrayBuffer())
);
}
},
});
}
3 changes: 3 additions & 0 deletions packages/php-wasm/universal/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export type {
SpawnHandler,
} from './universal-php';

export type { IteratePhpFilesOptions as IterateFilesOptions } from './iterate-files';
export { iteratePhpFiles as iterateFiles } from './iterate-files';

export { UnhandledRejectionsTarget } from './wasm-error-reporting';

export type { IteratePhpFilesOptions as IterateFilesOptions } from './iterate-files';
Expand Down
2 changes: 1 addition & 1 deletion packages/php-wasm/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"types": "index.d.ts",
"gitHead": "2f8d8f3cea548fbd75111e8659a92f601cddc593",
"engines": {
"node": ">=16.15.1",
"node": ">=18.18.2",
"npm": ">=8.11.0"
}
}
Loading