@openhps/protobuf 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +58 -38
- package/dist/cjs/InternalProtobufDeserializer.js +30 -15
- package/dist/cjs/InternalProtobufDeserializer.js.map +1 -1
- package/dist/cjs/InternalProtobufSerializer.js +7 -7
- package/dist/cjs/InternalProtobufSerializer.js.map +1 -1
- package/dist/cjs/PrimitiveWrapper.js +13 -0
- package/dist/cjs/PrimitiveWrapper.js.map +1 -0
- package/dist/cjs/ProtobufSerializer.js +27 -2
- package/dist/cjs/ProtobufSerializer.js.map +1 -1
- package/dist/cjs/bin/generator.js +3 -3
- package/dist/cjs/bin/generator.js.map +1 -1
- package/dist/cjs/generator/ObjectGenerator.js +30 -12
- package/dist/cjs/generator/ObjectGenerator.js.map +1 -1
- package/dist/cjs/generator/ProjectGenerator.js +89 -38
- package/dist/cjs/generator/ProjectGenerator.js.map +1 -1
- package/dist/cjs/generator/constants.js +11 -4
- package/dist/cjs/generator/constants.js.map +1 -1
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/tsconfig.bundle.cjs.tsbuildinfo +1 -0
- package/dist/esm/InternalProtobufDeserializer.js +30 -14
- package/dist/esm/InternalProtobufDeserializer.js.map +1 -1
- package/dist/esm/InternalProtobufSerializer.js +7 -6
- package/dist/esm/InternalProtobufSerializer.js.map +1 -1
- package/dist/esm/PrimitiveWrapper.js +9 -0
- package/dist/esm/PrimitiveWrapper.js.map +1 -0
- package/dist/esm/ProtobufSerializer.js +30 -5
- package/dist/esm/ProtobufSerializer.js.map +1 -1
- package/dist/esm/bin/generator.js +5 -5
- package/dist/esm/bin/generator.js.map +1 -1
- package/dist/esm/decorators/index.js +1 -1
- package/dist/esm/generator/ObjectGenerator.js +32 -14
- package/dist/esm/generator/ObjectGenerator.js.map +1 -1
- package/dist/esm/generator/ProjectGenerator.js +92 -40
- package/dist/esm/generator/ProjectGenerator.js.map +1 -1
- package/dist/esm/generator/ServiceGenerator.js +1 -1
- package/dist/esm/generator/constants.js +11 -4
- package/dist/esm/generator/constants.js.map +1 -1
- package/dist/esm/generator/index.js +3 -3
- package/dist/esm/index.js +2 -2
- package/dist/esm/package.json +3 -0
- package/dist/esm/tsconfig.bundle.esm.tsbuildinfo +1 -0
- package/dist/esm/tsconfig.bundle.types.tsbuildinfo +1 -0
- package/dist/types/InternalProtobufDeserializer.d.ts +0 -2
- package/dist/types/InternalProtobufDeserializer.d.ts.map +1 -1
- package/dist/types/InternalProtobufSerializer.d.ts +0 -2
- package/dist/types/InternalProtobufSerializer.d.ts.map +1 -1
- package/dist/types/PrimitiveWrapper.d.ts +8 -0
- package/dist/types/PrimitiveWrapper.d.ts.map +1 -0
- package/dist/types/ProtobufSerializer.d.ts +6 -0
- package/dist/types/ProtobufSerializer.d.ts.map +1 -1
- package/dist/types/generator/ObjectGenerator.d.ts +2 -8
- package/dist/types/generator/ObjectGenerator.d.ts.map +1 -1
- package/dist/types/generator/ProjectGenerator.d.ts +1 -1
- package/dist/types/generator/ProjectGenerator.d.ts.map +1 -1
- package/dist/types/generator/constants.d.ts +1 -1
- package/dist/types/generator/constants.d.ts.map +1 -1
- package/dist/web/openhps-protobuf.es.js +17112 -12881
- package/dist/web/openhps-protobuf.es.js.map +1 -1
- package/dist/web/openhps-protobuf.es.min.js +2 -1
- package/dist/web/openhps-protobuf.es.min.js.LICENSE.txt +19 -0
- package/dist/web/openhps-protobuf.es.min.js.map +1 -1
- package/dist/web/openhps-protobuf.js +17434 -14605
- package/dist/web/openhps-protobuf.js.map +1 -1
- package/dist/web/openhps-protobuf.min.js +2 -1
- package/dist/web/openhps-protobuf.min.js.LICENSE.txt +19 -0
- package/dist/web/openhps-protobuf.min.js.map +1 -1
- package/package.json +125 -94
- package/src/InternalProtobufDeserializer.ts +52 -34
- package/src/InternalProtobufSerializer.ts +9 -10
- package/src/PrimitiveWrapper.ts +9 -0
- package/src/ProtobufSerializer.ts +33 -2
- package/src/bin/generator.ts +4 -4
- package/src/generator/ObjectGenerator.ts +34 -21
- package/src/generator/ProjectGenerator.ts +100 -42
- package/src/generator/constants.ts +11 -4
- package/dist/esm5/InternalProtobufDeserializer.js +0 -147
- package/dist/esm5/InternalProtobufDeserializer.js.map +0 -1
- package/dist/esm5/InternalProtobufSerializer.js +0 -132
- package/dist/esm5/InternalProtobufSerializer.js.map +0 -1
- package/dist/esm5/ProtobufSerializer.js +0 -131
- package/dist/esm5/ProtobufSerializer.js.map +0 -1
- package/dist/esm5/bin/generator.js +0 -104
- package/dist/esm5/bin/generator.js.map +0 -1
- package/dist/esm5/decorators/index.js +0 -2
- package/dist/esm5/decorators/index.js.map +0 -1
- package/dist/esm5/decorators/options.js +0 -2
- package/dist/esm5/decorators/options.js.map +0 -1
- package/dist/esm5/generator/ObjectGenerator.js +0 -311
- package/dist/esm5/generator/ObjectGenerator.js.map +0 -1
- package/dist/esm5/generator/ProjectGenerator.js +0 -115
- package/dist/esm5/generator/ProjectGenerator.js.map +0 -1
- package/dist/esm5/generator/ProtobufGenerator.js +0 -27
- package/dist/esm5/generator/ProtobufGenerator.js.map +0 -1
- package/dist/esm5/generator/ServiceGenerator.js +0 -10
- package/dist/esm5/generator/ServiceGenerator.js.map +0 -1
- package/dist/esm5/generator/constants.js +0 -18
- package/dist/esm5/generator/constants.js.map +0 -1
- package/dist/esm5/generator/index.js +0 -4
- package/dist/esm5/generator/index.js.map +0 -1
- package/dist/esm5/generator/types.js +0 -2
- package/dist/esm5/generator/types.js.map +0 -1
- package/dist/esm5/index.js +0 -3
- package/dist/esm5/index.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,96 +1,127 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
"
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
2
|
+
"name": "@openhps/protobuf",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "OpenHPS Protocol Buffer Generator",
|
|
5
|
+
"author": "Maxim Van de Wynckel",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/OpenHPS/openhps-protobuf.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/OpenHPS/openhps-protobuf/issues"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://openhps.org",
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"type": "commonjs",
|
|
19
|
+
"sideEffects": false,
|
|
20
|
+
"main": "./dist/cjs/index.js",
|
|
21
|
+
"types": "./dist/types/index.d.ts",
|
|
22
|
+
"module": "./dist/esm/index.js",
|
|
23
|
+
"es2015": "./dist/esm/index.js",
|
|
24
|
+
"unpkg": "./dist/web/openhps-protobuf.min.js",
|
|
25
|
+
"jsdelivr": "./dist/web/openhps-protobuf.min.js",
|
|
26
|
+
"bin": {
|
|
27
|
+
"openhps-protobuf": "./dist/cjs/bin/generator.js"
|
|
28
|
+
},
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/types/index.d.ts",
|
|
32
|
+
"import": "./dist/esm/index.js",
|
|
33
|
+
"require": "./dist/cjs/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./package.json": "./package.json"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"dist/**/*",
|
|
39
|
+
"src/**/*",
|
|
40
|
+
"LICENSE"
|
|
41
|
+
],
|
|
42
|
+
"scripts": {
|
|
43
|
+
"benchmark:1": "ts-node test/bench/serialization.bench.ts",
|
|
44
|
+
"benchmark:2": "ts-node test/bench/socket.bench.ts",
|
|
45
|
+
"benchmark:3": "ts-node test/bench/mqtt.bench.ts",
|
|
46
|
+
"start": "node dist/cjs/bin/generator.js",
|
|
47
|
+
"start:debug": "ts-node src/bin/generator.ts",
|
|
48
|
+
"test": "mocha --config test/.mocharc.json",
|
|
49
|
+
"cover": "c8 mocha --config test/.mocharc.json",
|
|
50
|
+
"cover:ci": "c8 mocha --config test/.mocharc.ci.json && c8 report --reporter=cobertura",
|
|
51
|
+
"lint": "eslint . && node scripts/check-peers.mjs",
|
|
52
|
+
"clean": "shx rm -rf ./dist && shx rm -rf ./docs/out",
|
|
53
|
+
"build": "npm run clean && npm-run-all --parallel build:ts:* && npm run build:webpack",
|
|
54
|
+
"build:quick": "npm-run-all --parallel build:ts:* && npm run build:webpack",
|
|
55
|
+
"build:typedoc": "typedoc --options docs/typedoc.json",
|
|
56
|
+
"build:ts:cjs": "tsc --build ./tsconfig/tsconfig.bundle.cjs.json",
|
|
57
|
+
"build:ts:esm": "tsc --build ./tsconfig/tsconfig.bundle.esm.json && node ./scripts/finalize-esm.mjs",
|
|
58
|
+
"build:ts:types": "tsc --build ./tsconfig/tsconfig.bundle.types.json",
|
|
59
|
+
"build:webpack": "npm-run-all --parallel build:webpack:*",
|
|
60
|
+
"build:webpack:prod": "webpack --env prod --",
|
|
61
|
+
"build:webpack:dev": "webpack --env dev --",
|
|
62
|
+
"publish:development": "npm run bump:beta && npm publish --tag dev",
|
|
63
|
+
"publish:beta": "npm run bump:beta && npm publish --tag beta",
|
|
64
|
+
"publish:release": "npm run bump:beta && npm publish --tag latest",
|
|
65
|
+
"bump:development": "commit-and-tag-version --prerelease alpha -m 'chore(alpha): %s' --skip.changelog",
|
|
66
|
+
"bump:beta": "commit-and-tag-version --prerelease beta -m 'chore(beta): %s' --skip.changelog",
|
|
67
|
+
"bump:release": "commit-and-tag-version -m 'chore(release): %s' --skip.changelog",
|
|
68
|
+
"prepare": "husky",
|
|
69
|
+
"build:golden": "shx rm -rf test/golden/protos && node -r ./test/tsconfig.js test/helpers/build-protos.ts test/golden/protos"
|
|
70
|
+
},
|
|
71
|
+
"dependencies": {
|
|
72
|
+
"@inquirer/prompts": "^5.0.5",
|
|
73
|
+
"chalk": "^4.1.2",
|
|
74
|
+
"fs-extra": "^11.4.1",
|
|
75
|
+
"long": "^5.2.3",
|
|
76
|
+
"protobufjs": "^8.8.1",
|
|
77
|
+
"tslib": "^2.9.1",
|
|
78
|
+
"yargs": "^17.7.2"
|
|
79
|
+
},
|
|
80
|
+
"devDependencies": {
|
|
81
|
+
"@commitlint/cli": "^21.2.4",
|
|
82
|
+
"@commitlint/config-conventional": "^21.2.4",
|
|
83
|
+
"@eslint/js": "^9.39.5",
|
|
84
|
+
"@openhps/core": "^1.0.16",
|
|
85
|
+
"@openhps/mqtt": "^1.0.2",
|
|
86
|
+
"@openhps/rdf": "^1.1.7",
|
|
87
|
+
"@openhps/rf": "^1.0.4",
|
|
88
|
+
"@openhps/socket": "^0.1.8",
|
|
89
|
+
"@types/benchmark": "^2.1.5",
|
|
90
|
+
"@types/chai": "^5.2.2",
|
|
91
|
+
"@types/fs-extra": "^11.0.4",
|
|
92
|
+
"@types/mocha": "^10.0.10",
|
|
93
|
+
"@types/node": "^26.6.6",
|
|
94
|
+
"benchmark": "^2.1.4",
|
|
95
|
+
"buffer": "^6.0.3",
|
|
96
|
+
"c8": "^12.0.0",
|
|
97
|
+
"chai": "^6.3.0",
|
|
98
|
+
"commit-and-tag-version": "^13.3.0",
|
|
99
|
+
"eslint": "^9.39.5",
|
|
100
|
+
"eslint-config-prettier": "^10.1.8",
|
|
101
|
+
"eslint-plugin-import": "^2.32.0",
|
|
102
|
+
"eslint-plugin-jsdoc": "^65.4.5",
|
|
103
|
+
"eslint-plugin-prettier": "^5.5.7",
|
|
104
|
+
"globals": "^17.14.0",
|
|
105
|
+
"husky": "^9.1.7",
|
|
106
|
+
"lint-staged": "^17.6.0",
|
|
107
|
+
"mocha": "^11.8.0",
|
|
108
|
+
"mocha-junit-reporter": "^2.2.1",
|
|
109
|
+
"mocha-multi-reporters": "^1.5.2",
|
|
110
|
+
"npm-run-all": "^4.1.5",
|
|
111
|
+
"prettier": "^3.10.0",
|
|
112
|
+
"reflect-metadata": ">=0.2.2",
|
|
113
|
+
"shx": "^0.4.0",
|
|
114
|
+
"terser-webpack-plugin": "^5.3.14",
|
|
115
|
+
"ts-node": "^10.9.2",
|
|
116
|
+
"typedoc": "^0.28.20",
|
|
117
|
+
"typescript": "^5.9.3",
|
|
118
|
+
"typescript-eslint": "^8.72.2",
|
|
119
|
+
"webpack": "^5.112.2",
|
|
120
|
+
"webpack-cli": "^7.3.1",
|
|
121
|
+
"wkt": "^0.1.1"
|
|
122
|
+
},
|
|
123
|
+
"engines": {
|
|
124
|
+
"node": ">=22.0.0"
|
|
125
|
+
},
|
|
126
|
+
"packageManager": "npm@10.9.2"
|
|
96
127
|
}
|
|
@@ -10,18 +10,14 @@ import {
|
|
|
10
10
|
TypedJSON,
|
|
11
11
|
UUID,
|
|
12
12
|
} from '@openhps/core';
|
|
13
|
-
import * as protobuf from 'protobufjs';
|
|
14
13
|
import { AnyT, JsonObjectMetadata } from 'typedjson';
|
|
14
|
+
import type { Type } from 'protobufjs';
|
|
15
|
+
import { primitiveWrapper } from './PrimitiveWrapper';
|
|
15
16
|
|
|
16
17
|
export class InternalProtobufDeserializer extends Deserializer {
|
|
17
|
-
protected static primitiveWrapper: protobuf.Type;
|
|
18
|
-
|
|
19
18
|
constructor() {
|
|
20
19
|
super();
|
|
21
20
|
|
|
22
|
-
InternalProtobufDeserializer.primitiveWrapper = new protobuf.Type('PrimitiveWrapperMessage');
|
|
23
|
-
InternalProtobufDeserializer.primitiveWrapper.add(new protobuf.Field('value', 1, 'string'));
|
|
24
|
-
|
|
25
21
|
this.setDeserializationStrategy(Number, (object: any) => {
|
|
26
22
|
if (typeof object === 'number') {
|
|
27
23
|
return object;
|
|
@@ -121,7 +117,7 @@ export class InternalProtobufDeserializer extends Deserializer {
|
|
|
121
117
|
): IndexedObject | T | undefined {
|
|
122
118
|
let expectedSelfType = typeDescriptor.ctor;
|
|
123
119
|
let sourceObjectMetadata: ObjectMetadata = JsonObjectMetadata.getFromConstructor(expectedSelfType);
|
|
124
|
-
if (
|
|
120
|
+
if (Object.prototype.hasOwnProperty.call(sourceObject, '_type') && sourceObject._type !== 0) {
|
|
125
121
|
const enumTypeClassname = sourceObjectMetadata.protobuf.enumMapping.get(sourceObject._type);
|
|
126
122
|
if (enumTypeClassname) {
|
|
127
123
|
const enumType = knownTypes.get(enumTypeClassname);
|
|
@@ -131,18 +127,30 @@ export class InternalProtobufDeserializer extends Deserializer {
|
|
|
131
127
|
}
|
|
132
128
|
}
|
|
133
129
|
} else if (sourceObject.type_url && sourceObject.value) {
|
|
134
|
-
const MessageType = serializerOptions.types.get(sourceObject.type_url) as
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
130
|
+
const MessageType = serializerOptions.types.get(sourceObject.type_url) as Type;
|
|
131
|
+
if (MessageType) {
|
|
132
|
+
const message = MessageType.decode(sourceObject.value);
|
|
133
|
+
const data = this.convertAsObject(
|
|
134
|
+
message,
|
|
135
|
+
new ConcreteTypeDescriptor(knownTypes.get(sourceObject.type_url)),
|
|
136
|
+
knownTypes,
|
|
137
|
+
memberName,
|
|
138
|
+
deserializer,
|
|
139
|
+
memberOptions,
|
|
140
|
+
serializerOptions,
|
|
141
|
+
);
|
|
142
|
+
return data;
|
|
143
|
+
}
|
|
144
|
+
// Unknown type: fall back to the primitive wrapper for primitive values
|
|
145
|
+
const message = primitiveWrapper.decode(sourceObject.value) as any;
|
|
146
|
+
switch (sourceObject.type_url) {
|
|
147
|
+
case 'Boolean':
|
|
148
|
+
return (message.value === 'true') as any;
|
|
149
|
+
case 'Number':
|
|
150
|
+
return Number(message.value) as any;
|
|
151
|
+
default:
|
|
152
|
+
return message.value as any;
|
|
153
|
+
}
|
|
146
154
|
}
|
|
147
155
|
|
|
148
156
|
const sourceMetadata = sourceObjectMetadata;
|
|
@@ -162,32 +170,42 @@ export class InternalProtobufDeserializer extends Deserializer {
|
|
|
162
170
|
|
|
163
171
|
let revivedValue;
|
|
164
172
|
if (objMemberMetadata.name === 'uid') {
|
|
165
|
-
if (
|
|
173
|
+
if (
|
|
174
|
+
Object.prototype.hasOwnProperty.call(sourceObject, 'uid_bytes') &&
|
|
175
|
+
sourceObject['uid_bytes'].byteLength > 0
|
|
176
|
+
) {
|
|
166
177
|
revivedValue = UUID.fromBuffer(sourceObject['uid_bytes']).toString();
|
|
167
|
-
} else if (
|
|
178
|
+
} else if (Object.prototype.hasOwnProperty.call(sourceObject, 'uid_string')) {
|
|
168
179
|
revivedValue = sourceObject['uid_string'];
|
|
169
180
|
} else {
|
|
170
181
|
return;
|
|
171
182
|
}
|
|
172
|
-
} else if (
|
|
183
|
+
} else if (
|
|
184
|
+
!Object.prototype.hasOwnProperty.call(sourceObject, memberName) ||
|
|
185
|
+
objMemberValue === undefined ||
|
|
186
|
+
objMemberValue === null
|
|
187
|
+
) {
|
|
173
188
|
return;
|
|
174
189
|
} else if (objMemberMetadata.type() === AnyT && objMemberValue.type_url) {
|
|
175
|
-
const MessageType = serializerOptions.types.get(sourceObject[memberName].type_url) as
|
|
190
|
+
const MessageType = serializerOptions.types.get(sourceObject[memberName].type_url) as Type;
|
|
176
191
|
if (MessageType) {
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
message
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
192
|
+
const messageType = knownTypes.get(objMemberValue.type_url);
|
|
193
|
+
if (messageType !== undefined) {
|
|
194
|
+
const message = MessageType.decode(objMemberValue.value);
|
|
195
|
+
revivedValue = deserializer.convertSingleValue(
|
|
196
|
+
message,
|
|
197
|
+
new ConcreteTypeDescriptor(messageType),
|
|
198
|
+
knownTypes,
|
|
199
|
+
objMemberDebugName,
|
|
200
|
+
objMemberOptions,
|
|
201
|
+
serializerOptions,
|
|
202
|
+
);
|
|
203
|
+
}
|
|
186
204
|
} else if (objMemberValue.value) {
|
|
187
|
-
const message =
|
|
205
|
+
const message = primitiveWrapper.decode(objMemberValue.value) as any;
|
|
188
206
|
switch (objMemberValue.type_url) {
|
|
189
207
|
case 'Boolean':
|
|
190
|
-
revivedValue =
|
|
208
|
+
revivedValue = message.value === 'true';
|
|
191
209
|
break;
|
|
192
210
|
case 'Number':
|
|
193
211
|
revivedValue = Number(message.value);
|
|
@@ -9,18 +9,14 @@ import {
|
|
|
9
9
|
TypedJSON,
|
|
10
10
|
UUID,
|
|
11
11
|
} from '@openhps/core';
|
|
12
|
-
import { Type } from 'protobufjs';
|
|
13
12
|
import { AnyT, JsonObjectMetadata } from 'typedjson';
|
|
14
|
-
import
|
|
13
|
+
import type { Type } from 'protobufjs';
|
|
14
|
+
import { primitiveWrapper } from './PrimitiveWrapper';
|
|
15
15
|
|
|
16
16
|
export class InternalProtobufSerializer extends Serializer {
|
|
17
|
-
protected static primitiveWrapper: Type;
|
|
18
|
-
|
|
19
17
|
constructor() {
|
|
20
18
|
super();
|
|
21
19
|
this.setSerializationStrategy(Map, this.convertAsMap.bind(this));
|
|
22
|
-
InternalProtobufSerializer.primitiveWrapper = new protobuf.Type('PrimitiveWrapperMessage');
|
|
23
|
-
InternalProtobufSerializer.primitiveWrapper.add(new protobuf.Field('value', 1, 'string'));
|
|
24
20
|
}
|
|
25
21
|
|
|
26
22
|
convertSingleValue(
|
|
@@ -122,7 +118,10 @@ export class InternalProtobufSerializer extends Serializer {
|
|
|
122
118
|
}
|
|
123
119
|
} else {
|
|
124
120
|
const MessageType = sourceTypeMetadata.protobuf.messageType;
|
|
125
|
-
|
|
121
|
+
// Look the field up by its wire name: members renamed through
|
|
122
|
+
// `options.protobuf.name` are emitted under that name, so the
|
|
123
|
+
// metadata name would not resolve for them.
|
|
124
|
+
const field = MessageType.get(memberName);
|
|
126
125
|
serialized = this.convertSingleValue(
|
|
127
126
|
sourceObject[objMemberMetadata.key],
|
|
128
127
|
objMemberMetadata.type(),
|
|
@@ -139,7 +138,7 @@ export class InternalProtobufSerializer extends Serializer {
|
|
|
139
138
|
if (objMemberMetadata.type() === AnyT) {
|
|
140
139
|
const MessageType = serializerOptions.types.get(
|
|
141
140
|
sourceObject[objMemberMetadata.key].constructor.name,
|
|
142
|
-
) as
|
|
141
|
+
) as Type;
|
|
143
142
|
if (MessageType) {
|
|
144
143
|
const message = MessageType.create(serialized);
|
|
145
144
|
serialized = {
|
|
@@ -147,12 +146,12 @@ export class InternalProtobufSerializer extends Serializer {
|
|
|
147
146
|
value: MessageType.encode(message).finish(),
|
|
148
147
|
};
|
|
149
148
|
} else {
|
|
150
|
-
const message =
|
|
149
|
+
const message = primitiveWrapper.create({
|
|
151
150
|
value: String(sourceObject[objMemberMetadata.key]),
|
|
152
151
|
});
|
|
153
152
|
serialized = {
|
|
154
153
|
type_url: sourceObject[objMemberMetadata.key].constructor.name,
|
|
155
|
-
value:
|
|
154
|
+
value: primitiveWrapper.encode(message).finish(),
|
|
156
155
|
};
|
|
157
156
|
}
|
|
158
157
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as protobuf from 'protobufjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Protobuf type wrapping a primitive value as a string.
|
|
5
|
+
* Shared by the serializer and the deserializer as the `google.protobuf.Any`
|
|
6
|
+
* fallback for primitive values that protobuf cannot express directly.
|
|
7
|
+
*/
|
|
8
|
+
export const primitiveWrapper: protobuf.Type = new protobuf.Type('PrimitiveWrapperMessage');
|
|
9
|
+
primitiveWrapper.add(new protobuf.Field('value', 1, 'string'));
|
|
@@ -8,6 +8,12 @@ import { InternalProtobufSerializer } from './InternalProtobufSerializer';
|
|
|
8
8
|
|
|
9
9
|
export class ProtobufSerializer extends DataSerializer {
|
|
10
10
|
protected static wrapperMessage: protobuf.Type;
|
|
11
|
+
/**
|
|
12
|
+
* Root holding {@link wrapperMessage}. protobufjs 8 resolves edition features by
|
|
13
|
+
* walking up to a root, and throws "Unable to find a parent for WrapperMessage" for
|
|
14
|
+
* a Type that was never added to one. Held as a field so it stays reachable.
|
|
15
|
+
*/
|
|
16
|
+
protected static wrapperRoot: protobuf.Root;
|
|
11
17
|
protected static options: ProtobufSerializerConfig = {
|
|
12
18
|
serializer: new InternalProtobufSerializer(),
|
|
13
19
|
deserializer: new InternalProtobufDeserializer(),
|
|
@@ -39,6 +45,26 @@ export class ProtobufSerializer extends DataSerializer {
|
|
|
39
45
|
static initialize(directory?: string): Promise<void> {
|
|
40
46
|
return new Promise((resolve, reject) => {
|
|
41
47
|
ProtobufSerializer.root = new protobuf.Root();
|
|
48
|
+
// Reinitialisation (e.g. per test) must not accumulate stale type entries:
|
|
49
|
+
// build the new map first and only swap it in once the schemas have
|
|
50
|
+
// loaded, so a failed load keeps the previous types instead of wiping them
|
|
51
|
+
const types = new Map<string, protobuf.Type>();
|
|
52
|
+
// The generated schemas extend google.protobuf.EnumValueOptions, which is
|
|
53
|
+
// declared in descriptor.proto. protobufjs resolves imports relative to the
|
|
54
|
+
// origin file, so it looked for google/protobuf/descriptor.proto inside the
|
|
55
|
+
// generated output directory and failed with "unresolvable extensions".
|
|
56
|
+
// protobufjs ships the well-known types itself; point the resolver at them.
|
|
57
|
+
// Resolve the package root from a literal specifier: a template literal here
|
|
58
|
+
// makes webpack build a context module over the whole protobufjs package,
|
|
59
|
+
// which then tries to parse its .d.ts and tsconfig.json as bundle input.
|
|
60
|
+
const protobufRoot = path.dirname(require.resolve('protobufjs/package.json'));
|
|
61
|
+
const defaultResolve = ProtobufSerializer.root.resolvePath.bind(ProtobufSerializer.root);
|
|
62
|
+
ProtobufSerializer.root.resolvePath = (origin: string, target: string) => {
|
|
63
|
+
if (target.startsWith('google/protobuf/')) {
|
|
64
|
+
return path.join(protobufRoot, target);
|
|
65
|
+
}
|
|
66
|
+
return defaultResolve(origin, target);
|
|
67
|
+
};
|
|
42
68
|
Promise.resolve(
|
|
43
69
|
!directory ? (ProjectGenerator.buildProject(path.resolve('tmp')) as any) : Promise.resolve(),
|
|
44
70
|
)
|
|
@@ -88,9 +114,10 @@ export class ProtobufSerializer extends DataSerializer {
|
|
|
88
114
|
messageTypeEnum: enumNumber,
|
|
89
115
|
enumMapping,
|
|
90
116
|
};
|
|
91
|
-
|
|
117
|
+
types.set(className, MessageType);
|
|
92
118
|
}
|
|
93
119
|
});
|
|
120
|
+
this.options.types = types;
|
|
94
121
|
resolve();
|
|
95
122
|
})
|
|
96
123
|
.catch((error) => {
|
|
@@ -98,13 +125,14 @@ export class ProtobufSerializer extends DataSerializer {
|
|
|
98
125
|
});
|
|
99
126
|
});
|
|
100
127
|
|
|
128
|
+
this.wrapperRoot = new protobuf.Root();
|
|
101
129
|
this.wrapperMessage = new protobuf.Type('WrapperMessage');
|
|
102
130
|
this.wrapperMessage.add(new protobuf.Field('data', 1, 'google.protobuf.Any'));
|
|
103
131
|
this.wrapperMessage.addJSON(protobuf.common['google/protobuf/any.proto'].nested);
|
|
132
|
+
this.wrapperRoot.add(this.wrapperMessage);
|
|
104
133
|
return loadPromise;
|
|
105
134
|
})
|
|
106
135
|
.then(() => {
|
|
107
|
-
console.log(ProtobufSerializer.root.toJSON());
|
|
108
136
|
resolve();
|
|
109
137
|
})
|
|
110
138
|
.catch(reject);
|
|
@@ -147,6 +175,9 @@ export class ProtobufSerializer extends DataSerializer {
|
|
|
147
175
|
const decodedData: any = this.wrapperMessage.decode(serializedData);
|
|
148
176
|
const typeURL = decodedData.data.type_url;
|
|
149
177
|
const MessageType = this.options.types.get(typeURL) as protobuf.Type;
|
|
178
|
+
if (MessageType === undefined) {
|
|
179
|
+
throw new Error(`Unknown protobuf type '${typeURL}'`);
|
|
180
|
+
}
|
|
150
181
|
const decodedMessage = MessageType.decode(decodedData.data.value);
|
|
151
182
|
const finalType = dataType ?? (this.knownTypes.get(typeURL) as Constructor<T>);
|
|
152
183
|
return this.options.deserializer.convertSingleValue(
|
package/src/bin/generator.ts
CHANGED
|
@@ -20,9 +20,9 @@ import {
|
|
|
20
20
|
RelativeDistance,
|
|
21
21
|
} from '@openhps/core';
|
|
22
22
|
import { ProtobufSerializer } from '../ProtobufSerializer';
|
|
23
|
-
import
|
|
23
|
+
import assert from 'node:assert/strict';
|
|
24
24
|
|
|
25
|
-
const args
|
|
25
|
+
const args = yargs.argv;
|
|
26
26
|
const data = {
|
|
27
27
|
directory: path.normalize('tmp'),
|
|
28
28
|
};
|
|
@@ -114,13 +114,13 @@ function test(): Promise<void> {
|
|
|
114
114
|
frame.addObject(new DataObject('test2', 'Test Object 2'));
|
|
115
115
|
const buffer = ProtobufSerializer.serialize(frame);
|
|
116
116
|
const deserialized: DataFrame = ProtobufSerializer.deserialize(buffer);
|
|
117
|
-
|
|
117
|
+
assert.notStrictEqual(deserialized, undefined, 'deserialization returned undefined');
|
|
118
118
|
const compare1 = JSON.stringify(DataSerializer.serialize(deserialized), null, 2);
|
|
119
119
|
const compare2 = JSON.stringify(DataSerializer.serialize(frame), null, 2);
|
|
120
120
|
// console.log(compare1);
|
|
121
121
|
// console.log('\n');
|
|
122
122
|
// console.log(compare2);
|
|
123
|
-
|
|
123
|
+
assert.deepStrictEqual(compare1, compare2, 'round-tripped frame differs from the original');
|
|
124
124
|
console.log(chalk.green(`Basic serialization and deserialization test completed!`));
|
|
125
125
|
resolve();
|
|
126
126
|
})
|