Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve performance and bundled size #6

Merged
merged 10 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,21 @@ import arrayBuffer from "./typescript.svg?arraybuffer";
import uint8array from "./typescript.svg?uint8array";
```

Reduce compilation size
This module uses the primitive translation method to `int8` which will double the file size after compilation but it runs very fast because it can be copied directly to RAM.

However, for those who want the advantage of packet size there is an additional option called `base64` which will only increase the packet size by `20%` however it will require the browser to decode the base64 before it can be copied. gets into RAM
báe64

```main.ts
import arrayBuffer from "./typescript.svg?arraybuffer&base64";
import uint8array from "./typescript.svg?uint8array&base64";
```

Thanks [@kevlened](https://github.com/kevlened) for the `base64` support work done by



### TypeScript support

This plugin also supports typing for typescript
Expand Down
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
<script type="module" src="/src/main-web.ts"></script>
</body>
</html>
17 changes: 17 additions & 0 deletions src/main.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
import arrayBuffer from "./typescript.svg?arraybuffer";
import uint8array from "./typescript.svg?uint8array";
import arrayBufferB64 from "./typescript.svg?arraybuffer&base64";
import uint8arrayB64 from "./typescript.svg?uint8array&base64";
import crypto from "node:crypto";

import { describe, expect, test } from "vitest";

const hash = (buffer: ArrayBuffer) => crypto.createHash("md5").update(Buffer.from(buffer)).digest("hex");

describe("test plugin", () => {
test("?arraybuffer", () => {
expect(arrayBuffer[Symbol.toStringTag]).toBe("ArrayBuffer");
expect(arrayBuffer instanceof ArrayBuffer).toBe(true);
expect(hash(arrayBuffer)).toEqual("7167f7caac27a336c58b0c16cc5003d7");
});
test("?uint8array", () => {
expect(uint8array[Symbol.toStringTag]).toBe("Uint8Array");
expect(uint8array instanceof Uint8Array).toBe(true);
expect(hash(uint8array.buffer)).toEqual("7167f7caac27a336c58b0c16cc5003d7");
});
test("?arraybuffer&base64", () => {
expect(arrayBufferB64[Symbol.toStringTag]).toBe("ArrayBuffer");
expect(arrayBufferB64 instanceof ArrayBuffer).toBe(true);
expect(hash(arrayBufferB64)).toEqual("7167f7caac27a336c58b0c16cc5003d7");
});
test("?uint8array&base64", () => {
expect(uint8arrayB64[Symbol.toStringTag]).toBe("Uint8Array");
expect(uint8arrayB64 instanceof Uint8Array).toBe(true);
expect(hash(uint8arrayB64.buffer)).toEqual("7167f7caac27a336c58b0c16cc5003d7");
});
});
91 changes: 89 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,84 @@ import { promises } from "fs";
// eslint-disable-next-line n/no-extraneous-import
import { PluginOption } from "vite";

const decode64Raw = `function b64ToUint6(nChr) {
return nChr > 64 && nChr < 91
? nChr - 65
: nChr > 96 && nChr < 123
? nChr - 71
: nChr > 47 && nChr < 58
? nChr + 4
: nChr === 43
? 62
: nChr === 47
? 63
: 0
}

function base64ToUint8(sBase64, nBlocksSize) {
const sB64Enc = sBase64.replace(/[^A-Za-z0-9+/]/g, "")
const nInLen = sB64Enc.length
const nOutLen = nBlocksSize
? Math.ceil(((nInLen * 3 + 1) >> 2) / nBlocksSize) * nBlocksSize
: (nInLen * 3 + 1) >> 2
const taBytes = new Uint8Array(nOutLen)

let nMod3
let nMod4
let nUint24 = 0
let nOutIdx = 0
for (let nInIdx = 0; nInIdx < nInLen; nInIdx++) {
nMod4 = nInIdx & 3
nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4))
if (nMod4 === 3 || nInLen - nInIdx === 1) {
nMod3 = 0
while (nMod3 < 3 && nOutIdx < nOutLen) {
taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255
nMod3++
nOutIdx++
}
nUint24 = 0
}
}

return taBytes
}
function toUint8(b64) {
let bin = atob(b64)
let len = bin.length
let bytes = new Uint8Array(len)
for (let i = 0; i < len; i++) {
bytes[i] = bin.charCodeAt(i)
}
return bytes
}

const decode64 = typeof atob === "function" ? toUint8 : base64ToUint8

export default decode64
`

export default function vitePluginArraybuffer(): PluginOption {
return {
name: "vite-plugin-arraybuffer",
resolveId(id) {
if (id.endsWith("?arraybuffer") || id.endsWith("?uint8array")) {
if (
id.endsWith("?arraybuffer") ||
id.endsWith("?uint8array") ||
id.endsWith("?arraybuffer&base64") ||
id.endsWith("?uint8array&base64") ||
id === "virtual:decode-64"
) {
return id
}

return;
return
},
load(id) {
if (id === "virtual:decode-64") {
return decode64Raw
}
return
},
async transform(_src, id) {
if (id.endsWith("?arraybuffer")) {
Expand All @@ -30,6 +99,24 @@ export default function vitePluginArraybuffer(): PluginOption {
${new Uint8Array(await promises.readFile(file)).join(',')}
])`;
}
if (id.endsWith("?arraybuffer&base64")) {
const file = id.slice(0, -19)
this.addWatchFile(file)

const buffer = await promises.readFile(file)
const b64 = buffer.toString("base64")

return `import decode64 from 'virtual:decode-64'\nexport default decode64("${b64}").buffer`
}
if (id.endsWith("?uint8array&base64")) {
const file = id.slice(0, -18)
this.addWatchFile(file)

const buffer = await promises.readFile(file)
const b64 = buffer.toString("base64")

return `import decode64 from 'virtual:decode-64'\nexport default decode64("${b64}")`
}

return;
},
Expand Down
12 changes: 12 additions & 0 deletions src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,15 @@ declare module "*?uint8array" {

export default value;
}

declare module "*?arraybuffer&base64" {
const value: ArrayBuffer;

export default value;
}

declare module "*?uint8array&base64" {
const value: Uint8Array;

export default value;
}