Skip to content

Commit

Permalink
feat!: support no-copy serialization (#54)
Browse files Browse the repository at this point in the history
Accept Uint8ArrayLists as input for desrialization.

BREAKING CHANGE: Uses Uint8ArrayList v2
  • Loading branch information
achingbrain authored Jul 28, 2022
1 parent 9b973ee commit caa0d71
Show file tree
Hide file tree
Showing 15 changed files with 94 additions and 77 deletions.
2 changes: 1 addition & 1 deletion packages/protons-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
"release": "aegir release"
},
"dependencies": {
"uint8arraylist": "^1.4.0",
"uint8arraylist": "^2.0.0",
"uint8arrays": "^3.0.0"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/protons-runtime/src/codecs/bytes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const decode: DecodeFunction<Uint8Array> = function bytesDecode (buf, offset) {
const byteLength = unsigned.decode(buf, offset)
offset += unsigned.encodingLength(byteLength)

return buf.slice(offset, offset + byteLength)
return buf.subarray(offset, offset + byteLength)
}

export const bytes = createCodec('bytes', CODEC_TYPES.LENGTH_DELIMITED, encode, decode, encodingLength)
2 changes: 1 addition & 1 deletion packages/protons-runtime/src/codecs/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const decode: DecodeFunction<string> = function stringDecode (buf, offset) {
const strLen = unsigned.decode(buf, offset)
offset += unsigned.encodingLength(strLen)

return uint8ArrayToString(buf.slice(offset, offset + strLen))
return uint8ArrayToString(buf.subarray(offset, offset + strLen))
}

export const string = createCodec('string', CODEC_TYPES.LENGTH_DELIMITED, encode, decode, encodingLength)
6 changes: 3 additions & 3 deletions packages/protons-runtime/src/decode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { Uint8ArrayList } from 'uint8arraylist'
import { unsigned } from './utils/varint.js'
import type { Codec } from './codec.js'

export function decodeMessage <T> (buf: Uint8Array, codec: Codec<T>) {
export function decodeMessage <T> (buf: Uint8Array | Uint8ArrayList, codec: Codec<T>): T {
// wrap root message
const prefix = new Uint8Array(unsigned.encodingLength(buf.length))
unsigned.encode(buf.length, prefix)
const prefix = new Uint8Array(unsigned.encodingLength(buf.byteLength))
unsigned.encode(buf.byteLength, prefix)

return codec.decode(new Uint8ArrayList(prefix, buf), 0)
}
9 changes: 7 additions & 2 deletions packages/protons-runtime/src/encode.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { Uint8ArrayList } from 'uint8arraylist'
import type { Codec } from './codec.js'
import { unsigned } from './utils/varint.js'

export function encodeMessage <T> (message: T, codec: Codec<T>) {
export function encodeMessage <T> (message: T, codec: Codec<T>): Uint8ArrayList {
// unwrap root message
const encoded = codec.encode(message)
const skip = unsigned.encodingLength(unsigned.decode(encoded))

return encoded.slice(skip)
if (encoded instanceof Uint8Array) {
return new Uint8ArrayList(encoded.subarray(skip))
}

return encoded.sublist(skip)
}
3 changes: 2 additions & 1 deletion packages/protons/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@
"devDependencies": {
"aegir": "^37.0.5",
"pbjs": "^0.0.14",
"protons-runtime": "^1.0.0"
"protons-runtime": "^1.0.0",
"uint8arraylist": "^2.0.0"
}
}
8 changes: 6 additions & 2 deletions packages/protons/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,11 +216,11 @@ export interface ${messageDef.name} {
})
}
export const encode = (obj: ${messageDef.name}): Uint8Array => {
export const encode = (obj: ${messageDef.name}): Uint8ArrayList => {
return encodeMessage(obj, ${messageDef.name}.codec())
}
export const decode = (buf: Uint8Array): ${messageDef.name} => {
export const decode = (buf: Uint8Array | Uint8ArrayList): ${messageDef.name} => {
return decodeMessage(buf, ${messageDef.name}.codec())
}`
}
Expand Down Expand Up @@ -315,6 +315,10 @@ export async function generate (source: string, flags: Flags) {
lines.push(`import type { ${Array.from(moduleDef.importedTypes).join(', ')} } from 'protons-runtime'`)
}

if (moduleDef.imports.has('encodeMessage')) {
lines.push("import type { Uint8ArrayList } from 'uint8arraylist'")
}

lines = [
...lines,
'',
Expand Down
5 changes: 3 additions & 2 deletions packages/protons/test/fixtures/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import { encodeMessage, decodeMessage, message, string, int32 } from 'protons-runtime'
import type { Codec } from 'protons-runtime'
import type { Uint8ArrayList } from 'uint8arraylist'

export interface Basic {
foo: string
Expand All @@ -17,11 +18,11 @@ export namespace Basic {
})
}

export const encode = (obj: Basic): Uint8Array => {
export const encode = (obj: Basic): Uint8ArrayList => {
return encodeMessage(obj, Basic.codec())
}

export const decode = (buf: Uint8Array): Basic => {
export const decode = (buf: Uint8Array | Uint8ArrayList): Basic => {
return decodeMessage(buf, Basic.codec())
}
}
9 changes: 5 additions & 4 deletions packages/protons/test/fixtures/circuit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import { enumeration, encodeMessage, decodeMessage, message, bytes } from 'protons-runtime'
import type { Codec } from 'protons-runtime'
import type { Uint8ArrayList } from 'uint8arraylist'

export interface CircuitRelay {
type?: CircuitRelay.Type
Expand Down Expand Up @@ -89,11 +90,11 @@ export namespace CircuitRelay {
})
}

export const encode = (obj: Peer): Uint8Array => {
export const encode = (obj: Peer): Uint8ArrayList => {
return encodeMessage(obj, Peer.codec())
}

export const decode = (buf: Uint8Array): Peer => {
export const decode = (buf: Uint8Array | Uint8ArrayList): Peer => {
return decodeMessage(buf, Peer.codec())
}
}
Expand All @@ -107,11 +108,11 @@ export namespace CircuitRelay {
})
}

export const encode = (obj: CircuitRelay): Uint8Array => {
export const encode = (obj: CircuitRelay): Uint8ArrayList => {
return encodeMessage(obj, CircuitRelay.codec())
}

export const decode = (buf: Uint8Array): CircuitRelay => {
export const decode = (buf: Uint8Array | Uint8ArrayList): CircuitRelay => {
return decodeMessage(buf, CircuitRelay.codec())
}
}
Loading

0 comments on commit caa0d71

Please sign in to comment.