Skip to content

Commit

Permalink
chore: release v0.1.3
Browse files Browse the repository at this point in the history
  • Loading branch information
nonzzz committed Sep 2, 2024
1 parent 99adf8f commit 6610d87
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 16 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 0.1.3

## Patches

- Fix incorrect split chunk when process large files.

# 0.1.2

## Patches
Expand Down
26 changes: 23 additions & 3 deletions __tests__/stream.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ describe('Stream', () => {
const targetPath = path.join(__dirname, 'tpl')
const output = path.join(targetPath, 'node-v22.7.0')
fs.mkdirSync(targetPath, { recursive: true })
await x('tar', [`-xf${nodeTar}`, `-C${targetPath}`])
await x('tar', [`-xzf${nodeTar}`, `-C${targetPath}`])
const files = await readAll(output)
const extract = createExtract()
let c = 0
Expand All @@ -100,8 +100,6 @@ describe('Stream', () => {
}
})

extract.on('error', (e) => console.log(e))

const p = await new Promise((resolve) => {
const reader = fs.createReadStream(nodeTar)
const binary: Buffer[] = []
Expand All @@ -113,6 +111,28 @@ describe('Stream', () => {
extract.receiver.write(p)
extract.receiver.end()

await new Promise((resolve) => extract.on('close', resolve))
await fsp.rm(targetPath, { recursive: true })
expect(c).toBe(files.length)
})
it('@LongLink GNU tar2', async () => {
const nodeTar = path.join(fixturesPath, 'node-v22.7.0.tar.gz')
const targetPath = path.join(__dirname, 'tpl')
const output = path.join(targetPath, 'node-v22.7.0')
fs.mkdirSync(targetPath, { recursive: true })
await x('tar', [`-xzf${nodeTar}`, `-C${targetPath}`])
const files = await readAll(output)
const extract = createExtract()
let c = 0
extract.on('entry', (head) => {
if (head.typeflag === TypeFlag.REG_TYPE) {
c += 1
}
})

const reader = fs.createReadStream(nodeTar)
reader.pipe(zlib.createUnzip()).pipe(extract.receiver)

await new Promise((resolve) => extract.on('close', resolve))
await fsp.rm(targetPath, { recursive: true })
expect(c).toBe(files.length)
Expand Down
4 changes: 4 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Example

> [!IMPORTANT]
> This sample example might not support work on windows.
29 changes: 29 additions & 0 deletions example/extract.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import fs from 'fs'
import path from 'path'
import zlib from 'zlib'
import { createExtract } from 'tar-mini'
import { setupEnv } from './setup.js'

const [ok, symPath] = setupEnv()

async function main() {
if (!ok) {
console.error('An error occurred')
process.exit(1)
}
const extract = createExtract()
const gz = path.join(symPath, 'node-v22.7.0.tar.gz')
const readable = fs.createReadStream(gz)

const unzip = zlib.createUnzip()

extract.on('entry', (head) => {
console.log(head.name)
})

readable.pipe(unzip).pipe(extract.receiver)

await new Promise((resolve) => extract.on('close', resolve))
}

main()
7 changes: 7 additions & 0 deletions example/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"private": true,
"type": "module",
"devDependencies": {
"tar-mini": "workspace:*"
}
}
22 changes: 22 additions & 0 deletions example/setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import fs from 'fs'
import url from 'url'
import path from 'path'

const __dirname = path.dirname(url.fileURLToPath(import.meta.url))

const TARGET_FIXTURES_PATH = path.join(path.dirname(__dirname), '__tests__', 'fixtures')

const OUTPUT_PATH = path.join(__dirname, 'tpl')

export function setupEnv() {
if (fs.existsSync(OUTPUT_PATH)) {
return [true, OUTPUT_PATH]
}

try {
fs.symlinkSync(TARGET_FIXTURES_PATH, OUTPUT_PATH, 'dir')
return [true, OUTPUT_PATH]
} catch (error) {
return [false, '']
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tar-mini",
"version": "0.1.2",
"version": "0.1.3",
"description": "It's an implementation based on the `ustar` format",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
10 changes: 4 additions & 6 deletions pnpm-lock.yaml

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

2 changes: 2 additions & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
packages:
- 'example'
31 changes: 25 additions & 6 deletions src/stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,11 @@ class FastBytes {
throw new Error(FAST_BYTES_ERROR_MESSAGES.EXCEED_BYTES_LEN)
}
const elt = this.queue.peek()

if (!elt) {
throw new Error(FAST_BYTES_ERROR_MESSAGES.EXCEED_BYTES_LEN)
}

return elt.subarray(0, size)
}
}
Expand All @@ -186,6 +188,7 @@ export class Extract {
private isNonUSTAR: boolean
private paxMeta: Record<string, string>
private gnuMeta: Record<string, string>
private pause: boolean
constructor(options: DecodingHeadOptions) {
this.decodeOptions = options
this.matrix = new FastBytes()
Expand All @@ -198,9 +201,19 @@ export class Extract {
this.isNonUSTAR = false
this.paxMeta = Object.create(null)
this.gnuMeta = Object.create(null)
this.pause = false
this.writer = createWriteableStream({
write: (chunk, _, callback) => {
this.matrix.push(chunk)
if (this.pause) {
const bb = this.matrix.shift(this.matrix.bytesLen)
const next = new Uint8Array(bb.length + chunk.length)
next.set(bb)
next.set(chunk, bb.length)
this.matrix.push(next)
this.pause = false
} else {
this.matrix.push(chunk)
}
this.transport()
callback()
}
Expand All @@ -221,6 +234,7 @@ export class Extract {
const decodeHead = () => {
try {
this.head = decode(this.matrix.shift(512), this.decodeOptions)

if (!ensureIsStandardUSTARFormat(this.head.typeflag)) {
this.isNonUSTAR = true
return true
Expand Down Expand Up @@ -322,11 +336,16 @@ export class Extract {
continue
}

const c = this.matrix.peek(512)

if (c[0] === Magic.NULL_CHAR && c[511] === Magic.NULL_CHAR) {
this.matrix.shift(512)
continue
try {
const c = this.matrix.peek(512)
if (c[0] === Magic.NULL_CHAR && c[511] === Magic.NULL_CHAR) {
this.matrix.shift(512)
continue
}
} catch (_) {
// In some case the last chunk of the file is not enough to fill the 512 bytes
this.pause = true
return
}

if (!decodeHead()) return
Expand Down

0 comments on commit 6610d87

Please sign in to comment.