Skip to content

Commit

Permalink
fix: update aegir, make codec creation dynamic (#26)
Browse files Browse the repository at this point in the history
To avoid having to work out which classes depend on which, make codec generation dynamic.

Also upgrade to latest aegir.
  • Loading branch information
achingbrain committed Apr 8, 2022
1 parent 64fe094 commit ecc46cc
Show file tree
Hide file tree
Showing 18 changed files with 951 additions and 77 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"build": "lerna run build",
"lint": "lerna run lint",
"dep-check": "lerna run dep-check",
"release": "lerna run release --concurrency 1"
"release": "lerna run release --concurrency 1 -- --"
},
"dependencies": {
"lerna": "^4.0.0",
Expand Down
8 changes: 8 additions & 0 deletions packages/protons-benchmark/.aegir.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

export default {
build: {
config: {
platform: 'node'
}
}
}
7 changes: 4 additions & 3 deletions packages/protons-benchmark/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@
]
},
"scripts": {
"clean": "aegir clean",
"lint": "aegir lint",
"dep-check": "aegir dep-check dist/src/**/*.js dist/test/**/*.js",
"build": "tsc && cp src/protobufjs/bench.js dist/src/protobufjs",
"dep-check": "aegir dep-check",
"build": "aegir build && cp -R src/protobufjs dist/src/protobufjs",
"prestart": "npm run build",
"start": "node dist/src/index.js"
},
Expand All @@ -73,7 +74,7 @@
"protons-runtime": "^0.0.0"
},
"devDependencies": {
"aegir": "^36.1.3"
"aegir": "^37.0.5"
},
"private": true
}
2 changes: 1 addition & 1 deletion packages/protons-benchmark/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

import benny from 'benny'
import { expect } from 'aegir/utils/chai.js'
import { expect } from 'aegir/chai'
import { Test as ProtonsTest } from './protons/bench.js'
import { encodeTest as pbjsEncodeTest, decodeTest as pbjsDecodeTest } from './pbjs/bench.js'
import { Test as ProtobufjsTest } from './protobufjs/bench.js'
Expand Down
1 change: 1 addition & 0 deletions packages/protons-benchmark/src/protobufjs/bench.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*eslint-disable*/
// @ts-nocheck

import $protobuf from "protobufjs/minimal.js";

// Common aliases
Expand Down
72 changes: 42 additions & 30 deletions packages/protons-benchmark/src/protons/bench.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@ export interface Foo {
}

export namespace Foo {
export const codec = message<Foo>({
1: { name: 'baz', codec: uint32 }
})
export const codec = () => {
return message<Foo>({
1: { name: 'baz', codec: uint32 }
})
}

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

export const decode = (buf: Uint8Array): Foo => {
return decodeMessage(buf, Foo.codec)
return decodeMessage(buf, Foo.codec())
}
}

Expand All @@ -26,16 +28,18 @@ export interface Bar {
}

export namespace Bar {
export const codec = message<Bar>({
1: { name: 'tmp', codec: Foo.codec }
})
export const codec = () => {
return message<Bar>({
1: { name: 'tmp', codec: Foo.codec() }
})
}

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

export const decode = (buf: Uint8Array): Bar => {
return decodeMessage(buf, Bar.codec)
return decodeMessage(buf, Bar.codec())
}
}

Expand All @@ -45,24 +49,28 @@ export enum FOO {
}

export namespace FOO {
export const codec = enumeration<typeof FOO>(FOO)
export const codec = () => {
return enumeration<typeof FOO>(FOO)
}
}

export interface Yo {
lol: FOO[]
}

export namespace Yo {
export const codec = message<Yo>({
1: { name: 'lol', codec: FOO.codec, repeats: true }
})
export const codec = () => {
return message<Yo>({
1: { name: 'lol', codec: FOO.codec(), repeats: true }
})
}

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

export const decode = (buf: Uint8Array): Yo => {
return decodeMessage(buf, Yo.codec)
return decodeMessage(buf, Yo.codec())
}
}

Expand All @@ -72,17 +80,19 @@ export interface Lol {
}

export namespace Lol {
export const codec = message<Lol>({
1: { name: 'lol', codec: string },
2: { name: 'b', codec: Bar.codec }
})
export const codec = () => {
return message<Lol>({
1: { name: 'lol', codec: string },
2: { name: 'b', codec: Bar.codec() }
})
}

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

export const decode = (buf: Uint8Array): Lol => {
return decodeMessage(buf, Lol.codec)
return decodeMessage(buf, Lol.codec())
}
}

Expand All @@ -94,18 +104,20 @@ export interface Test {
}

export namespace Test {
export const codec = message<Test>({
6: { name: 'meh', codec: Lol.codec },
3: { name: 'hello', codec: uint32 },
1: { name: 'foo', codec: string },
7: { name: 'payload', codec: bytes }
})
export const codec = () => {
return message<Test>({
6: { name: 'meh', codec: Lol.codec() },
3: { name: 'hello', codec: uint32 },
1: { name: 'foo', codec: string },
7: { name: 'payload', codec: bytes }
})
}

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

export const decode = (buf: Uint8Array): Test => {
return decodeMessage(buf, Test.codec)
return decodeMessage(buf, Test.codec())
}
}
4 changes: 1 addition & 3 deletions packages/protons-benchmark/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
{
"extends": "aegir/src/config/tsconfig.aegir.json",
"compilerOptions": {
"outDir": "dist",
"emitDeclarationOnly": false,
"module": "ES2020"
"outDir": "dist"
},
"include": [
"bin",
Expand Down
8 changes: 4 additions & 4 deletions packages/protons-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,15 @@
},
"scripts": {
"lint": "aegir lint",
"dep-check": "aegir dep-check dist/src/**/*.js dist/test/**/*.js",
"build": "tsc",
"release": "semantic-release -e semantic-release-monorepo"
"dep-check": "aegir dep-check",
"build": "aegir build",
"release": "aegir release"
},
"dependencies": {
"uint8arraylist": "^1.4.0",
"uint8arrays": "^3.0.0"
},
"devDependencies": {
"aegir": "^36.1.3"
"aegir": "^37.0.5"
}
}
17 changes: 2 additions & 15 deletions packages/protons-runtime/src/codecs/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,10 @@ export function message <T> (fieldDefs: FieldDefs): Codec<T> {
const decode: DecodeFunction<T> = function messageDecode (buffer, offset) {
const length = unsigned.decode(buffer, offset)
offset += unsigned.encodingLength(length)

const end = offset + length
const fields: any = {}

while (offset < buffer.length) {
// console.info('start offset', offset)

while (offset < end) {
const key = unsigned.decode(buffer, offset)
offset += unsigned.encodingLength(key)

Expand All @@ -78,10 +76,7 @@ export function message <T> (fieldDefs: FieldDefs): Codec<T> {
const fieldDef = fieldDefs[fieldNumber]
let fieldLength = 0

// console.info('fieldNumber', fieldNumber, 'wireType', wireType, 'offset', offset)

if (wireType === CODEC_TYPES.VARINT) {
// console.info('decode varint')
if (fieldDef != null) {
// use the codec if it is available as this could be a bigint
const value = fieldDef.codec.decode(buffer, offset)
Expand All @@ -91,25 +86,19 @@ export function message <T> (fieldDefs: FieldDefs): Codec<T> {
fieldLength = unsigned.encodingLength(value)
}
} else if (wireType === CODEC_TYPES.BIT64) {
// console.info('decode 64bit')
fieldLength = 8
} else if (wireType === CODEC_TYPES.LENGTH_DELIMITED) {
// console.info('decode length delimited')
const valueLength = unsigned.decode(buffer, offset)
fieldLength = valueLength + unsigned.encodingLength(valueLength)
} else if (wireType === CODEC_TYPES.BIT32) {
// console.info('decode 32 bit')
fieldLength = 4
} else if (wireType === CODEC_TYPES.START_GROUP) {
throw new Error('Unsupported wire type START_GROUP')
} else if (wireType === CODEC_TYPES.END_GROUP) {
throw new Error('Unsupported wire type END_GROUP')
}

// console.info('fieldLength', fieldLength)

if (fieldDef != null) {
// console.info('decode', fieldDef.codec.name, fieldDef.name, 'at offset', offset)
const value = fieldDef.codec.decode(buffer, offset)

if (fieldDef.repeats === true) {
Expand All @@ -121,8 +110,6 @@ export function message <T> (fieldDefs: FieldDefs): Codec<T> {
} else {
fields[fieldDef.name] = value
}

// console.info('decoded', value)
}

offset += fieldLength
Expand Down
8 changes: 8 additions & 0 deletions packages/protons/.aegir.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

export default {
build: {
config: {
platform: 'node'
}
}
}
13 changes: 6 additions & 7 deletions packages/protons/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,19 +141,18 @@
},
"scripts": {
"lint": "aegir lint",
"dep-check": "aegir dep-check dist/src/**/*.js dist/test/**/*.js",
"build": "tsc",
"pretest": "npm run build",
"test": "aegir test -t node -f ./dist/test/*.js -f ./dist/test/**/*.js",
"test:node": "npm run test -- -t node --cov",
"release": "semantic-release -e semantic-release-monorepo"
"dep-check": "aegir dep-check",
"build": "aegir build",
"test": "aegir test -t node",
"test:node": "aegir test -t node --cov",
"release": "aegir release"
},
"dependencies": {
"meow": "^10.1.2",
"protobufjs": "^6.11.2"
},
"devDependencies": {
"aegir": "^36.1.3",
"aegir": "^37.0.5",
"pbjs": "^0.0.14",
"protons-runtime": "^1.0.0"
}
Expand Down
22 changes: 13 additions & 9 deletions packages/protons/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,16 @@ function compileMessage (messageDef: MessageDef, moduleDef: ModuleDef): string {
return `
export enum ${messageDef.name} {
${
Object.entries(messageDef.values).map(([enumValueName, enumValue]) => {
Object.keys(messageDef.values).map(enumValueName => {
return `${enumValueName} = '${enumValueName}'`
}).join(',\n ').trim()
}
}
export namespace ${messageDef.name} {
export const codec = enumeration<typeof ${messageDef.name}>(${messageDef.name})
export const codec = () => {
return enumeration<typeof ${messageDef.name}>(${messageDef.name})
}
}
`
}
Expand Down Expand Up @@ -173,8 +175,9 @@ export interface ${messageDef.name} {
}
export namespace ${messageDef.name} {${nested}
export const codec = message<${messageDef.name}>({
${Object.entries(fields)
export const codec = () => {
return message<${messageDef.name}>({
${Object.entries(fields)
.map(([name, fieldDef]) => {
let codec = encoders[fieldDef.type]
Expand All @@ -188,21 +191,22 @@ export namespace ${messageDef.name} {${nested}
}
const typeName = findTypeName(fieldDef.type, messageDef, moduleDef)
codec = `${typeName}.codec`
codec = `${typeName}.codec()`
} else {
moduleDef.imports.add(codec)
}
return `${fieldDef.id}: { name: '${name}', codec: ${codec}${fieldDef.options?.proto3_optional === true ? ', optional: true' : ''}${fieldDef.rule === 'repeated' ? ', repeats: true' : ''} }`
}).join(',\n ')}
})
}).join(',\n ')}
})
}
export const encode = (obj: ${messageDef.name}): Uint8Array => {
return encodeMessage(obj, ${messageDef.name}.codec)
return encodeMessage(obj, ${messageDef.name}.codec())
}
export const decode = (buf: Uint8Array): ${messageDef.name} => {
return decodeMessage(buf, ${messageDef.name}.codec)
return decodeMessage(buf, ${messageDef.name}.codec())
}
}
`
Expand Down
Loading

0 comments on commit ecc46cc

Please sign in to comment.