diff --git a/docs/examples/fs.md b/docs/examples/fs.md index 26508ef..ed6fc91 100644 --- a/docs/examples/fs.md +++ b/docs/examples/fs.md @@ -20,3 +20,23 @@ const value = client.get('key'); console.log(value); ``` + +## 3. Use `msgpack` serializer + +By default `JSON` serializer is used. You can use following code to use `msgpack` serializer. + +```typescript +import { Client } from '@litehex/storage-box'; +import { FsDriver } from '@litehex/storage-box/driver'; +import { MSGPack } from '@litehex/storage-box/parser'; + +const filePath = resovle(process.cwd(), 'data.pack'); +const driver = new FsDriver(filePath, { parser: MSGPack }); +const client = new Client(driver); + +client.set('key', 'value'); + +const value = client.get('key'); + +console.log(value); +``` diff --git a/package.json b/package.json index ae7ffa2..f549fc0 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ }, "packageManager": "pnpm@8.15.1", "dependencies": { + "@msgpack/msgpack": "3.0.0-beta2", "debounce": "^2.0.0", "type-fest": "^4.10.2" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f2ad4d9..2817b19 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,6 +5,9 @@ settings: excludeLinksFromLockfile: false dependencies: + '@msgpack/msgpack': + specifier: 3.0.0-beta2 + version: 3.0.0-beta2 debounce: specifier: ^2.0.0 version: 2.0.0 @@ -292,6 +295,11 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true + /@msgpack/msgpack@3.0.0-beta2: + resolution: {integrity: sha512-y+l1PNV0XDyY8sM3YtuMLK5vE3/hkfId+Do8pLo/OPxfxuFAUwcGz3oiiUuV46/aBpwTzZ+mRWVMtlSKbradhw==} + engines: {node: '>= 14'} + dev: false + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} diff --git a/src/index.ts b/src/index.ts index 89851c0..ddebd41 100644 --- a/src/index.ts +++ b/src/index.ts @@ -287,4 +287,4 @@ export type * from '@/typings.ts'; // ----------- -export { JsonMap } from '@/parser'; +export { JsonMap, MSGPack } from '@/parser'; diff --git a/src/parser/index.ts b/src/parser/index.ts index 57022d7..9b852dc 100644 --- a/src/parser/index.ts +++ b/src/parser/index.ts @@ -1 +1,2 @@ export * as JsonMap from './json-map.ts'; +export * as MSGPack from './msg-pack.ts'; diff --git a/src/parser/msg-pack.ts b/src/parser/msg-pack.ts new file mode 100644 index 0000000..e73ea1c --- /dev/null +++ b/src/parser/msg-pack.ts @@ -0,0 +1,26 @@ +import type { JsonValue } from 'type-fest'; +import { decode, encode } from '@msgpack/msgpack'; + +export function parse(data: any): Map { + if (typeof data !== 'string') { + throw new Error('MessagePack data must be a string'); + } + const buffer = Buffer.from(data, 'base64'); + const decoded = decode(buffer); + + if (typeof decoded !== 'object') { + throw new Error('MessagePack data must be an object'); + } + + return new Map(Object.entries(decoded as object)); +} + +export function stringify(data: any): string { + if (!(data instanceof Map)) { + throw new Error('MessagePack data must be a Map'); + } + const obj = Object.fromEntries(data); + const encoded = encode(obj); + const buffer = Buffer.from(encoded.buffer, encoded.byteOffset, encoded.byteLength); + return buffer.toString('base64'); +} diff --git a/tests/parser.test.ts b/tests/parser.test.ts index 7a4e240..5248afc 100644 --- a/tests/parser.test.ts +++ b/tests/parser.test.ts @@ -1,12 +1,12 @@ -import { JsonMap } from '@/parser'; +import { JsonMap, MSGPack } from '@/parser'; import { expect } from 'chai'; -describe('JSON-MAP', () => { - const data = { - foo: 'bar', - bar: 'baz' - }; +const data = { + foo: 'bar', + bar: 'baz' +}; +describe('JSON-MAP', () => { it('stringify', () => { const hashMap = new Map(); hashMap.set('foo', 'bar'); @@ -20,3 +20,29 @@ describe('JSON-MAP', () => { expect(hashMap.get('foo')).to.equal('bar'); }); }); + +describe('MSGPack-MAP', () => { + function isBase64(str: string): boolean { + // Regular expression to check if a string is base64 encoded + const base64Regex = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/; + + return base64Regex.test(str); + } + + it('stringify', () => { + const hashMap = new Map(); + hashMap.set('foo', 'bar'); + hashMap.set('bar', 'baz'); + const msgPack = MSGPack.stringify(hashMap); + expect(isBase64(msgPack)).to.be.true; + + console.log(msgPack); + }); + + it('parse', () => { + const msgPack = MSGPack.stringify(new Map(Object.entries(data))); + const hashMap = MSGPack.parse(msgPack); + expect(hashMap.get('foo')).to.equal('bar'); + expect(hashMap.get('bar')).to.equal('baz'); + }); +});