fix(build): align TypeScript and test imports with NodeNext builds and safely copy Uint8Array inputs in browser processing

This commit is contained in:
2026-05-01 16:10:01 +00:00
parent aa976061b1
commit c4dc34cd1a
14 changed files with 2811 additions and 4447 deletions
+39
View File
@@ -0,0 +1,39 @@
{
"@git.zone/cli": {
"projectType": "npm",
"module": {
"githost": "code.foss.global",
"gitscope": "push.rocks",
"gitrepo": "smartpreview",
"shortDescription": "A library for generating efficient JPEG previews from PDFs",
"description": "A library for generating efficient JPEG previews from PDFs with support for Node.js and browser environments",
"npmPackagename": "@push.rocks/smartpreview",
"license": "MIT",
"keywords": [
"pdf",
"preview",
"jpeg",
"image",
"conversion",
"nodejs",
"browser",
"pdfjs",
"worker"
]
},
"release": {
"registries": [
"https://verdaccio.lossless.digital",
"https://registry.npmjs.org"
],
"accessLevel": "public"
}
},
"@git.zone/tsdoc": {
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license.md](license.md) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
},
"@ship.zone/szci": {
"npmGlobalTools": [],
"npmRegistryUrl": "registry.npmjs.org"
}
}
+7
View File
@@ -1,5 +1,12 @@
# Changelog
## 2026-05-01 - 1.1.1 - fix(build)
align TypeScript and test imports with NodeNext builds and safely copy Uint8Array inputs in browser processing
- switches the project to NodeNext-oriented TypeScript configuration and updates tests to import built .js entrypoints
- replaces direct Uint8Array buffer slicing with explicit ArrayBuffer copies in browser code paths to avoid incorrect input handling
- refreshes package metadata, published files, formatting script, and dependency versions to match the updated build setup
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+3 -3
View File
@@ -1,6 +1,6 @@
# MIT License
The MIT License (MIT)
Copyright (C) 2024 Task Venture Capital GmbH
Copyright (c) 2026 Task Venture Capital GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
+37 -11
View File
@@ -1,13 +1,39 @@
{
"githost": "code.foss.global",
"gitscope": "push.rocks",
"gitrepo": "smartpreview",
"shortDescription": "A library for generating efficient JPEG previews from PDFs",
"npmAccessLevel": "public",
"npmRegistries": [
"npmjs"
],
"tsdoc": {
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require different licensing, please contact: legal@task.vc\n"
"@git.zone/cli": {
"projectType": "npm",
"module": {
"githost": "code.foss.global",
"gitscope": "push.rocks",
"gitrepo": "smartpreview",
"shortDescription": "A library for generating efficient JPEG previews from PDFs",
"description": "A library for generating efficient JPEG previews from PDFs with support for Node.js and browser environments",
"npmPackagename": "@push.rocks/smartpreview",
"license": "MIT",
"keywords": [
"pdf",
"preview",
"jpeg",
"image",
"conversion",
"nodejs",
"browser",
"pdfjs",
"worker"
]
},
"release": {
"registries": [
"https://verdaccio.lossless.digital",
"https://registry.npmjs.org"
],
"accessLevel": "public"
}
},
"@git.zone/tsdoc": {
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license.md](license.md) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
},
"@ship.zone/szci": {
"npmGlobalTools": [],
"npmRegistryUrl": "registry.npmjs.org"
}
}
}
+27 -10
View File
@@ -12,7 +12,8 @@
},
"scripts": {
"test": "(tstest test/ --web)",
"build": "(tsbuild tsfolders --allowimplicitany)",
"build": "tsbuild tsfolders",
"format": "gitzone format",
"buildDocs": "tsdoc"
},
"repository": {
@@ -30,19 +31,21 @@
"pdfjs",
"worker"
],
"author": "Lossless GmbH",
"author": "Task Venture Capital GmbH <hello@task.vc>",
"license": "MIT",
"dependencies": {
"@push.rocks/smartpdf": "^4.0.0",
"@push.rocks/smartenv": "^5.0.5",
"@push.rocks/smartjson": "^5.0.10",
"@push.rocks/smartpromise": "^4.0.3"
"@push.rocks/smartenv": "^6.1.0",
"@push.rocks/smartjson": "^6.0.1",
"@push.rocks/smartpdf": "^4.2.2",
"@push.rocks/smartpromise": "^4.2.3"
},
"devDependencies": {
"@git.zone/tsbuild": "^2.1.70",
"@git.zone/tsrun": "^1.2.46",
"@git.zone/tstest": "^1.0.81",
"@types/node": "^20.6.3"
"@git.zone/tsbuild": "^4.4.0",
"@git.zone/tsrun": "^2.0.3",
"@git.zone/tstest": "^3.6.3",
"@types/lodash.clonedeep": "^4.5.9",
"@types/node": "^25.6.0",
"@types/pngjs": "^6.0.5"
},
"engines": {
"node": ">=16"
@@ -50,5 +53,19 @@
"browserslist": [
"last 1 Chrome version"
],
"files": [
"ts/**/*",
"ts_web/**/*",
"dist/**/*",
"dist_*/**/*",
"dist_ts/**/*",
"dist_ts_web/**/*",
"assets/**/*",
"cli.js",
".smartconfig.json",
"license.md",
"npmextra.json",
"readme.md"
],
"packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977"
}
+2629 -4389
View File
File diff suppressed because it is too large Load Diff
+16 -4
View File
@@ -1,5 +1,5 @@
import { expect, tap } from '@git.zone/tstest/tapbundle';
import * as smartpreview from '../ts_web/index.ts';
import * as smartpreview from '../ts_web/index.js';
// Test data - minimal PDF as Uint8Array for browser testing
const createMinimalPdfBuffer = (): Uint8Array => {
@@ -74,10 +74,16 @@ startxref
return new TextEncoder().encode(pdfContent);
};
const uint8ArrayToArrayBuffer = (input: Uint8Array): ArrayBuffer => {
const arrayBuffer = new ArrayBuffer(input.byteLength);
new Uint8Array(arrayBuffer).set(input);
return arrayBuffer;
};
// Create a mock File object for testing
const createMockPdfFile = (): File => {
const buffer = createMinimalPdfBuffer();
return new File([buffer], 'test.pdf', { type: 'application/pdf' });
return new File([uint8ArrayToArrayBuffer(buffer)], 'test.pdf', { type: 'application/pdf' });
};
tap.test('should check browser compatibility', async () => {
@@ -117,6 +123,9 @@ tap.test('should throw error when not initialized', async () => {
expect(true).toEqual(false); // Should not reach here
} catch (error) {
expect(error).toBeInstanceOf(smartpreview.PreviewError);
if (!(error instanceof smartpreview.PreviewError)) {
throw error;
}
expect(error.errorType).toEqual('PROCESSING_FAILED');
}
});
@@ -129,6 +138,9 @@ tap.test('should validate input', async () => {
expect(true).toEqual(false); // Should not reach here
} catch (error) {
expect(error).toBeInstanceOf(smartpreview.PreviewError);
if (!(error instanceof smartpreview.PreviewError)) {
throw error;
}
expect(error.errorType).toEqual('PROCESSING_FAILED');
}
});
@@ -298,7 +310,7 @@ tap.test('should measure different input type processing times', async () => {
// Test ArrayBuffer input
const buffer = createMinimalPdfBuffer();
const arrayBuffer = buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
const arrayBuffer = uint8ArrayToArrayBuffer(buffer);
const bufferStartTime = performance.now();
try {
await preview.generatePreview(arrayBuffer, { quality: 70, width: 300, height: 200 });
@@ -367,4 +379,4 @@ tap.test('should measure progress callback overhead', async () => {
}
});
export default tap.start();
export default tap.start();
+7 -1
View File
@@ -1,5 +1,5 @@
import { expect, tap } from '@git.zone/tstest/tapbundle';
import * as smartpreview from '../ts/index.ts';
import * as smartpreview from '../ts/index.js';
// Test data - minimal PDF buffer for testing
const createMinimalPdf = (): Buffer => {
@@ -105,6 +105,9 @@ tap.test('should throw error when not initialized', async () => {
expect(true).toEqual(false); // Should not reach here
} catch (error) {
expect(error).toBeInstanceOf(smartpreview.PreviewError);
if (!(error instanceof smartpreview.PreviewError)) {
throw error;
}
expect(error.errorType).toEqual('PROCESSING_FAILED');
}
});
@@ -117,6 +120,9 @@ tap.test('should validate input buffer', async () => {
expect(true).toEqual(false); // Should not reach here
} catch (error) {
expect(error).toBeInstanceOf(smartpreview.PreviewError);
if (!(error instanceof smartpreview.PreviewError)) {
throw error;
}
expect(error.errorType).toEqual('PROCESSING_FAILED');
}
});
+7 -4
View File
@@ -277,7 +277,8 @@ tap.test('Performance Benchmark Suite', async () => {
await preview.cleanup();
} catch (error) {
console.log(` ❌ Test skipped: ${error.message}\n`);
const errorMessage = error instanceof Error ? error.message : String(error);
console.log(` ❌ Test skipped: ${errorMessage}\n`);
// Expected if dependencies are not available
expect(error).toBeInstanceOf(smartpreview.PreviewError);
}
@@ -356,7 +357,8 @@ tap.test('Memory Usage Analysis', async () => {
await preview.cleanup();
} catch (error) {
console.log(`❌ Memory test skipped: ${error.message}`);
const errorMessage = error instanceof Error ? error.message : String(error);
console.log(`❌ Memory test skipped: ${errorMessage}`);
expect(error).toBeInstanceOf(smartpreview.PreviewError);
}
});
@@ -407,9 +409,10 @@ tap.test('Stress Test - Rapid Conversions', async () => {
await preview.cleanup();
} catch (error) {
console.log(`❌ Stress test skipped: ${error.message}`);
const errorMessage = error instanceof Error ? error.message : String(error);
console.log(`❌ Stress test skipped: ${errorMessage}`);
expect(error).toBeInstanceOf(smartpreview.PreviewError);
}
});
export default tap.start();
export default tap.start();
+8
View File
@@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @push.rocks/commitinfo
*/
export const commitinfo = {
name: '@push.rocks/smartpreview',
version: '1.1.1',
description: 'A library for generating efficient JPEG previews from PDFs with support for Node.js and browser environments'
}
+8
View File
@@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @push.rocks/commitinfo
*/
export const commitinfo = {
name: '@push.rocks/smartpreview',
version: '1.1.1',
description: 'A library for generating efficient JPEG previews from PDFs with support for Node.js and browser environments'
}
+8 -2
View File
@@ -146,7 +146,7 @@ export class WebPdfProcessor implements IWebPdfProcessor {
}
if (input instanceof Uint8Array) {
return input.buffer.slice(input.byteOffset, input.byteOffset + input.byteLength);
return this.uint8ArrayToArrayBuffer(input);
}
if (input instanceof File || input instanceof Blob) {
@@ -420,4 +420,10 @@ export class WebPdfProcessor implements IWebPdfProcessor {
reader.readAsDataURL(blob);
});
}
}
private uint8ArrayToArrayBuffer(input: Uint8Array): ArrayBuffer {
const arrayBuffer = new ArrayBuffer(input.byteLength);
new Uint8Array(arrayBuffer).set(input);
return arrayBuffer;
}
}
+8 -2
View File
@@ -243,7 +243,7 @@ export class SmartPreview {
if (input instanceof ArrayBuffer) {
buffer = input;
} else if (input instanceof Uint8Array) {
buffer = input.buffer.slice(input.byteOffset, input.byteOffset + input.byteLength);
buffer = this.uint8ArrayToArrayBuffer(input);
} else if (input instanceof File || input instanceof Blob) {
// Read first few bytes to detect format
const headerBlob = input.slice(0, 8);
@@ -299,4 +299,10 @@ export class SmartPreview {
await instance.init();
return instance;
}
}
private uint8ArrayToArrayBuffer(input: Uint8Array): ArrayBuffer {
const arrayBuffer = new ArrayBuffer(input.byteLength);
new Uint8Array(arrayBuffer).set(input);
return arrayBuffer;
}
}
+7 -21
View File
@@ -1,29 +1,15 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022", "DOM"],
"module": "ESNext",
"moduleResolution": "node",
"declaration": true,
"outDir": "./dist_ts/",
"rootDir": "./ts/",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"noImplicitAny": true,
"strict": true,
"esModuleInterop": true,
"skipLibCheck": false,
"forceConsistentCasingInFileNames": true,
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"resolveJsonModule": true,
"allowJs": false
"verbatimModuleSyntax": true,
"types": ["node"]
},
"include": [
"ts/**/*"
],
"exclude": [
"node_modules",
"dist_ts",
"dist_ts_web",
"test"
"dist_*/**/*.d.ts"
]
}
}