@aztec/bb.js 1.2.1 → 2.0.0-nightly.20250813
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/dest/browser/barretenberg/backend.d.ts.map +1 -1
- package/dest/browser/barretenberg/backend.js +56 -45
- package/dest/browser/barretenberg/index.d.ts +10 -0
- package/dest/browser/barretenberg/index.d.ts.map +1 -1
- package/dest/browser/barretenberg/index.js +30 -2
- package/dest/browser/barretenberg/verifier.js +2 -2
- package/dest/browser/barretenberg_api/index.d.ts +2 -2
- package/dest/browser/barretenberg_api/index.d.ts.map +1 -1
- package/dest/browser/barretenberg_api/index.js +5 -5
- package/dest/browser/barretenberg_wasm/barretenberg_wasm_base/index.d.ts +1 -0
- package/dest/browser/barretenberg_wasm/barretenberg_wasm_base/index.d.ts.map +1 -1
- package/dest/browser/barretenberg_wasm/barretenberg_wasm_base/index.js +5 -4
- package/dest/browser/barretenberg_wasm/barretenberg_wasm_main/index.d.ts +2 -0
- package/dest/browser/barretenberg_wasm/barretenberg_wasm_main/index.d.ts.map +1 -1
- package/dest/browser/barretenberg_wasm/barretenberg_wasm_main/index.js +17 -1
- package/dest/browser/barretenberg_wasm/barretenberg_wasm_thread/index.d.ts +1 -0
- package/dest/browser/barretenberg_wasm/barretenberg_wasm_thread/index.d.ts.map +1 -1
- package/dest/browser/barretenberg_wasm/fetch_code/browser/barretenberg-threads.js +1 -1
- package/dest/browser/barretenberg_wasm/fetch_code/browser/barretenberg.js +1 -1
- package/dest/browser/cbind/generate.d.ts +5 -0
- package/dest/browser/cbind/generate.d.ts.map +1 -0
- package/dest/browser/cbind/generate.js +64 -0
- package/dest/browser/cbind/generated/api_types.d.ts +801 -0
- package/dest/browser/cbind/generated/api_types.d.ts.map +1 -0
- package/dest/browser/cbind/generated/api_types.js +1099 -0
- package/dest/browser/cbind/generated/async.d.ts +27 -0
- package/dest/browser/cbind/generated/async.d.ts.map +1 -0
- package/dest/browser/cbind/generated/async.js +184 -0
- package/dest/browser/cbind/generated/native.d.ts +35 -0
- package/dest/browser/cbind/generated/native.d.ts.map +1 -0
- package/dest/browser/cbind/generated/native.js +270 -0
- package/dest/browser/cbind/generated/sync.d.ts +27 -0
- package/dest/browser/cbind/generated/sync.d.ts.map +1 -0
- package/dest/browser/cbind/generated/sync.js +165 -0
- package/dest/browser/cbind/schema_compiler.d.ts +70 -0
- package/dest/browser/cbind/schema_compiler.d.ts.map +1 -0
- package/dest/browser/cbind/schema_compiler.js +683 -0
- package/dest/node/barretenberg/backend.d.ts.map +1 -1
- package/dest/node/barretenberg/backend.js +56 -45
- package/dest/node/barretenberg/index.d.ts +10 -0
- package/dest/node/barretenberg/index.d.ts.map +1 -1
- package/dest/node/barretenberg/index.js +30 -2
- package/dest/node/barretenberg/verifier.js +2 -2
- package/dest/node/barretenberg_api/index.d.ts +2 -2
- package/dest/node/barretenberg_api/index.d.ts.map +1 -1
- package/dest/node/barretenberg_api/index.js +5 -5
- package/dest/node/barretenberg_wasm/barretenberg-threads.wasm.gz +0 -0
- package/dest/node/barretenberg_wasm/barretenberg_wasm_base/index.d.ts +1 -0
- package/dest/node/barretenberg_wasm/barretenberg_wasm_base/index.d.ts.map +1 -1
- package/dest/node/barretenberg_wasm/barretenberg_wasm_base/index.js +5 -4
- package/dest/node/barretenberg_wasm/barretenberg_wasm_main/index.d.ts +2 -0
- package/dest/node/barretenberg_wasm/barretenberg_wasm_main/index.d.ts.map +1 -1
- package/dest/node/barretenberg_wasm/barretenberg_wasm_main/index.js +17 -1
- package/dest/node/barretenberg_wasm/barretenberg_wasm_thread/index.d.ts +1 -0
- package/dest/node/barretenberg_wasm/barretenberg_wasm_thread/index.d.ts.map +1 -1
- package/dest/node/cbind/generate.d.ts +5 -0
- package/dest/node/cbind/generate.d.ts.map +1 -0
- package/dest/node/cbind/generate.js +64 -0
- package/dest/node/cbind/generated/api_types.d.ts +801 -0
- package/dest/node/cbind/generated/api_types.d.ts.map +1 -0
- package/dest/node/cbind/generated/api_types.js +1099 -0
- package/dest/node/cbind/generated/async.d.ts +27 -0
- package/dest/node/cbind/generated/async.d.ts.map +1 -0
- package/dest/node/cbind/generated/async.js +184 -0
- package/dest/node/cbind/generated/native.d.ts +35 -0
- package/dest/node/cbind/generated/native.d.ts.map +1 -0
- package/dest/node/cbind/generated/native.js +270 -0
- package/dest/node/cbind/generated/sync.d.ts +27 -0
- package/dest/node/cbind/generated/sync.d.ts.map +1 -0
- package/dest/node/cbind/generated/sync.js +165 -0
- package/dest/node/cbind/schema_compiler.d.ts +70 -0
- package/dest/node/cbind/schema_compiler.d.ts.map +1 -0
- package/dest/node/cbind/schema_compiler.js +683 -0
- package/dest/node/main.js +3 -3
- package/dest/node-cjs/barretenberg/backend.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg/backend.js +58 -47
- package/dest/node-cjs/barretenberg/index.d.ts +10 -0
- package/dest/node-cjs/barretenberg/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg/index.js +30 -2
- package/dest/node-cjs/barretenberg/verifier.js +2 -2
- package/dest/node-cjs/barretenberg_api/index.d.ts +2 -2
- package/dest/node-cjs/barretenberg_api/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg_api/index.js +5 -5
- package/dest/node-cjs/barretenberg_wasm/barretenberg-threads.wasm.gz +0 -0
- package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_base/index.d.ts +1 -0
- package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_base/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_base/index.js +5 -4
- package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_main/index.d.ts +2 -0
- package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_main/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_main/index.js +17 -1
- package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_thread/index.d.ts +1 -0
- package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_thread/index.d.ts.map +1 -1
- package/dest/node-cjs/cbind/generate.d.ts +5 -0
- package/dest/node-cjs/cbind/generate.d.ts.map +1 -0
- package/dest/node-cjs/cbind/generate.js +66 -0
- package/dest/node-cjs/cbind/generated/api_types.d.ts +801 -0
- package/dest/node-cjs/cbind/generated/api_types.d.ts.map +1 -0
- package/dest/node-cjs/cbind/generated/api_types.js +1189 -0
- package/dest/node-cjs/cbind/generated/async.d.ts +27 -0
- package/dest/node-cjs/cbind/generated/async.d.ts.map +1 -0
- package/dest/node-cjs/cbind/generated/async.js +188 -0
- package/dest/node-cjs/cbind/generated/native.d.ts +35 -0
- package/dest/node-cjs/cbind/generated/native.d.ts.map +1 -0
- package/dest/node-cjs/cbind/generated/native.js +274 -0
- package/dest/node-cjs/cbind/generated/sync.d.ts +27 -0
- package/dest/node-cjs/cbind/generated/sync.d.ts.map +1 -0
- package/dest/node-cjs/cbind/generated/sync.js +169 -0
- package/dest/node-cjs/cbind/schema_compiler.d.ts +70 -0
- package/dest/node-cjs/cbind/schema_compiler.d.ts.map +1 -0
- package/dest/node-cjs/cbind/schema_compiler.js +691 -0
- package/dest/node-cjs/main.js +3 -3
- package/package.json +4 -3
- package/src/barretenberg/backend.ts +62 -63
- package/src/barretenberg/index.ts +39 -1
- package/src/barretenberg/verifier.ts +1 -1
- package/src/barretenberg_api/index.ts +4 -4
- package/src/barretenberg_wasm/barretenberg_wasm_base/index.ts +5 -3
- package/src/barretenberg_wasm/barretenberg_wasm_main/index.ts +23 -0
- package/src/cbind/README.md +1 -0
- package/src/cbind/generate.ts +89 -0
- package/src/cbind/schema_compiler.ts +832 -0
- package/src/main.ts +2 -2
|
@@ -0,0 +1,832 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified schema compiler with integrated strategies
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Core type definitions
|
|
6
|
+
export type Schema =
|
|
7
|
+
| string
|
|
8
|
+
| ObjectSchema
|
|
9
|
+
| ['tuple', Schema[]]
|
|
10
|
+
| ['map', [Schema, Schema]]
|
|
11
|
+
| ['optional', [Schema]]
|
|
12
|
+
| ['vector', [Schema]]
|
|
13
|
+
| ['variant', Schema[]]
|
|
14
|
+
| ['named_union', Array<[string, Schema]>]
|
|
15
|
+
| ['shared_ptr', [Schema]]
|
|
16
|
+
| ['array', [Schema, number]]
|
|
17
|
+
| ['alias', [string, string]];
|
|
18
|
+
|
|
19
|
+
export type ObjectSchema = { [key: string]: Schema };
|
|
20
|
+
|
|
21
|
+
export interface TypeInfo {
|
|
22
|
+
typeName: string;
|
|
23
|
+
msgpackTypeName?: string;
|
|
24
|
+
declaration?: string;
|
|
25
|
+
toMethod?: string;
|
|
26
|
+
fromMethod?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface FunctionMetadata {
|
|
30
|
+
name: string;
|
|
31
|
+
commandType: string;
|
|
32
|
+
responseType: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Compiler configuration
|
|
36
|
+
export interface CompilerConfig {
|
|
37
|
+
mode: 'types' | 'sync' | 'async' | 'native';
|
|
38
|
+
imports?: string[];
|
|
39
|
+
wasmImport?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Helper functions
|
|
43
|
+
function capitalize(s: string): string {
|
|
44
|
+
return s.charAt(0).toUpperCase() + s.substring(1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function camelCase(s: string): string {
|
|
48
|
+
return s
|
|
49
|
+
.split('_')
|
|
50
|
+
.map((part, index) => (index === 0 ? part.charAt(0).toLowerCase() + part.substring(1) : capitalize(part)))
|
|
51
|
+
.join('');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function pascalCase(s: string): string {
|
|
55
|
+
return s.split('_').map(capitalize).join('');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export class SchemaCompiler {
|
|
59
|
+
private typeCache = new Map<string, TypeInfo>();
|
|
60
|
+
private functionMetadata: FunctionMetadata[] = [];
|
|
61
|
+
// WORKTODO(bbapi): AI slop fixup - redundant with typeCache, remove
|
|
62
|
+
private referencedTypes = new Set<string>();
|
|
63
|
+
|
|
64
|
+
constructor(private config: CompilerConfig) {}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Process API schema and extract function metadata
|
|
68
|
+
*/
|
|
69
|
+
processApiSchema(commandsSchema: Schema, responsesSchema: Schema): void {
|
|
70
|
+
// Process types
|
|
71
|
+
this.processSchema(commandsSchema);
|
|
72
|
+
this.processSchema(responsesSchema);
|
|
73
|
+
|
|
74
|
+
// Extract function metadata from named unions
|
|
75
|
+
if (!Array.isArray(commandsSchema) || commandsSchema[0] !== 'named_union' ||
|
|
76
|
+
!Array.isArray(responsesSchema) || responsesSchema[0] !== 'named_union') {
|
|
77
|
+
throw new Error('Expected named_union schema format');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const commands = commandsSchema[1] as Array<[string, Schema]>;
|
|
81
|
+
const responses = responsesSchema[1] as Array<[string, Schema]>;
|
|
82
|
+
|
|
83
|
+
for (let i = 0; i < commands.length; i++) {
|
|
84
|
+
const [commandName] = commands[i];
|
|
85
|
+
const [responseName] = responses[i];
|
|
86
|
+
|
|
87
|
+
this.functionMetadata.push({
|
|
88
|
+
name: camelCase(commandName),
|
|
89
|
+
commandType: pascalCase(commandName),
|
|
90
|
+
responseType: pascalCase(responseName),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Process a schema and populate type cache
|
|
97
|
+
*/
|
|
98
|
+
processSchema(schema: Schema): TypeInfo {
|
|
99
|
+
const key = this.getSchemaKey(schema);
|
|
100
|
+
if (this.typeCache.has(key)) {
|
|
101
|
+
return this.typeCache.get(key)!;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const typeInfo = this.generateTypeInfo(schema);
|
|
105
|
+
this.typeCache.set(key, typeInfo);
|
|
106
|
+
return typeInfo;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Generate the complete output
|
|
111
|
+
*/
|
|
112
|
+
compile(): string {
|
|
113
|
+
const parts: string[] = [
|
|
114
|
+
'// AUTOGENERATED FILE - DO NOT EDIT',
|
|
115
|
+
'',
|
|
116
|
+
];
|
|
117
|
+
|
|
118
|
+
// Generate imports
|
|
119
|
+
parts.push(...this.generateImports());
|
|
120
|
+
parts.push('');
|
|
121
|
+
|
|
122
|
+
// Generate type declarations only for 'types' mode
|
|
123
|
+
if (this.config.mode === 'types') {
|
|
124
|
+
const sortedTypes = Array.from(this.typeCache.values())
|
|
125
|
+
.filter(t => t.declaration)
|
|
126
|
+
.sort((a, b) => a.typeName.localeCompare(b.typeName));
|
|
127
|
+
|
|
128
|
+
// Group declarations
|
|
129
|
+
const typeAliases = sortedTypes.filter(t =>
|
|
130
|
+
t.declaration?.startsWith('export type') && !t.declaration?.includes('interface')
|
|
131
|
+
);
|
|
132
|
+
const publicInterfaces = sortedTypes.filter(t =>
|
|
133
|
+
t.declaration?.includes('export interface')
|
|
134
|
+
);
|
|
135
|
+
const privateInterfaces = sortedTypes.filter(t =>
|
|
136
|
+
t.declaration?.includes('interface Msgpack')
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// Add type aliases if needed
|
|
140
|
+
if (typeAliases.length > 0) {
|
|
141
|
+
parts.push('// Type aliases');
|
|
142
|
+
for (const type of typeAliases) {
|
|
143
|
+
parts.push(type.declaration!);
|
|
144
|
+
}
|
|
145
|
+
parts.push('');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Add tuple helper if needed
|
|
149
|
+
if (this.needsTupleHelper()) {
|
|
150
|
+
parts.push(
|
|
151
|
+
'// Tuple type for fixed-size arrays',
|
|
152
|
+
'type Tuple<T, N extends number> = N extends N ? (number extends N ? T[] : _TupleOf<T, N, []>) : never;',
|
|
153
|
+
'type _TupleOf<T, N extends number, R extends unknown[]> = R[\'length\'] extends N ? R : _TupleOf<T, N, [T, ...R]>;',
|
|
154
|
+
'',
|
|
155
|
+
'// Helper functions',
|
|
156
|
+
'function mapTuple<T, S, N extends number>(tuple: Tuple<T, N>, fn: (item: T) => S): Tuple<S, N> {',
|
|
157
|
+
' return tuple.map(fn) as Tuple<S, N>;',
|
|
158
|
+
'}',
|
|
159
|
+
''
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Add public interfaces
|
|
164
|
+
if (publicInterfaces.length > 0) {
|
|
165
|
+
parts.push('// Public interfaces (exported)');
|
|
166
|
+
for (const type of publicInterfaces) {
|
|
167
|
+
parts.push(type.declaration!, '');
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Add private interfaces
|
|
172
|
+
if (privateInterfaces.length > 0) {
|
|
173
|
+
parts.push('// Private Msgpack interfaces (not exported)');
|
|
174
|
+
for (const type of privateInterfaces) {
|
|
175
|
+
parts.push(type.declaration!, '');
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Add conversion functions (only for api_types.ts)
|
|
180
|
+
const conversions = sortedTypes.filter(t => t.toMethod || t.fromMethod);
|
|
181
|
+
if (conversions.length > 0) {
|
|
182
|
+
parts.push('// Conversion functions (exported)');
|
|
183
|
+
for (const type of conversions) {
|
|
184
|
+
if (type.toMethod) {
|
|
185
|
+
parts.push('export ' + type.toMethod, '');
|
|
186
|
+
}
|
|
187
|
+
if (type.fromMethod) {
|
|
188
|
+
parts.push('export ' + type.fromMethod, '');
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Add BbApiBase interface
|
|
194
|
+
if (this.functionMetadata.length > 0) {
|
|
195
|
+
parts.push('', '// Base API interface');
|
|
196
|
+
parts.push(this.generateBbApiBaseInterface());
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Add API class for non-types modes
|
|
201
|
+
if (this.config.mode !== 'types' && this.functionMetadata.length > 0) {
|
|
202
|
+
parts.push(this.generateApiClass());
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return parts.join('\n') + '\n';
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
private getSchemaKey(schema: Schema): string {
|
|
209
|
+
if (typeof schema === 'string') return schema;
|
|
210
|
+
if (Array.isArray(schema)) return JSON.stringify(schema);
|
|
211
|
+
if (typeof schema === 'object') return (schema as any).__typename || JSON.stringify(schema);
|
|
212
|
+
return String(schema);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
private needsTupleHelper(): boolean {
|
|
216
|
+
return Array.from(this.typeCache.values()).some(t =>
|
|
217
|
+
t.typeName.includes('Tuple<')
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
private trackTypeUsage(typeName: string): void {
|
|
222
|
+
// Only track for API modes
|
|
223
|
+
if (this.config.mode === 'types') return;
|
|
224
|
+
|
|
225
|
+
// Extract base types from complex types
|
|
226
|
+
const baseTypes = this.extractBaseTypes(typeName);
|
|
227
|
+
|
|
228
|
+
for (const type of baseTypes) {
|
|
229
|
+
// Skip built-in types
|
|
230
|
+
if (['string', 'number', 'boolean', 'Uint8Array'].includes(type)) {
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
this.referencedTypes.add(type);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
private extractBaseTypes(typeName: string): string[] {
|
|
239
|
+
const types: string[] = [];
|
|
240
|
+
|
|
241
|
+
// Handle arrays
|
|
242
|
+
const arrayMatch = typeName.match(/^(.+)\[\]$/);
|
|
243
|
+
if (arrayMatch) {
|
|
244
|
+
types.push(...this.extractBaseTypes(arrayMatch[1]));
|
|
245
|
+
return types;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Handle Tuple
|
|
249
|
+
const tupleMatch = typeName.match(/^Tuple<(.+),\s*\d+>$/);
|
|
250
|
+
if (tupleMatch) {
|
|
251
|
+
types.push(...this.extractBaseTypes(tupleMatch[1]));
|
|
252
|
+
return types;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Handle Record
|
|
256
|
+
const recordMatch = typeName.match(/^Record<(.+),\s*(.+)>$/);
|
|
257
|
+
if (recordMatch) {
|
|
258
|
+
types.push(...this.extractBaseTypes(recordMatch[1]));
|
|
259
|
+
types.push(...this.extractBaseTypes(recordMatch[2]));
|
|
260
|
+
return types;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Handle union types
|
|
264
|
+
if (typeName.includes(' | ')) {
|
|
265
|
+
const parts = typeName.split(' | ');
|
|
266
|
+
for (const part of parts) {
|
|
267
|
+
types.push(...this.extractBaseTypes(part.trim()));
|
|
268
|
+
}
|
|
269
|
+
return types;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Base case - simple type
|
|
273
|
+
types.push(typeName);
|
|
274
|
+
return types;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
private generateTypeInfo(schema: Schema): TypeInfo {
|
|
278
|
+
if (Array.isArray(schema)) {
|
|
279
|
+
return this.processArraySchema(schema);
|
|
280
|
+
} else if (typeof schema === 'string') {
|
|
281
|
+
return this.processPrimitiveSchema(schema);
|
|
282
|
+
} else if (typeof schema === 'object') {
|
|
283
|
+
return this.processObjectSchema(schema);
|
|
284
|
+
}
|
|
285
|
+
throw new Error(`Unsupported schema type: ${schema}`);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
private processArraySchema(schema: any[]): TypeInfo {
|
|
289
|
+
const [type, ...args] = schema;
|
|
290
|
+
|
|
291
|
+
switch (type) {
|
|
292
|
+
case 'array': {
|
|
293
|
+
const [subtype, size] = args[0];
|
|
294
|
+
const subtypeInfo = this.processSchema(subtype);
|
|
295
|
+
return {
|
|
296
|
+
typeName: `Tuple<${subtypeInfo.typeName}, ${size}>`,
|
|
297
|
+
msgpackTypeName: `Tuple<${subtypeInfo.msgpackTypeName || subtypeInfo.typeName}, ${size}>`,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
case 'variant': {
|
|
302
|
+
const variants = args[0] as Schema[];
|
|
303
|
+
const variantInfos = variants.map(v => this.processSchema(v));
|
|
304
|
+
const typeName = variantInfos.map(v => v.typeName).join(' | ');
|
|
305
|
+
const msgpackUnion = variantInfos.map(v => v.msgpackTypeName || v.typeName).join(' | ');
|
|
306
|
+
return {
|
|
307
|
+
typeName,
|
|
308
|
+
msgpackTypeName: `[number, ${msgpackUnion}]`,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
case 'named_union': {
|
|
313
|
+
const namedTypes = args[0] as Array<[string, Schema]>;
|
|
314
|
+
const tupleTypes: string[] = [];
|
|
315
|
+
|
|
316
|
+
for (const [name, schemaOrName] of namedTypes) {
|
|
317
|
+
let typeInfo: TypeInfo;
|
|
318
|
+
if (typeof schemaOrName === 'string') {
|
|
319
|
+
const typeName = pascalCase(schemaOrName);
|
|
320
|
+
typeInfo = this.getOrCreateEmptyType(typeName);
|
|
321
|
+
} else {
|
|
322
|
+
typeInfo = this.processSchema(schemaOrName);
|
|
323
|
+
}
|
|
324
|
+
// Track usage of the type
|
|
325
|
+
this.trackTypeUsage(typeInfo.typeName);
|
|
326
|
+
tupleTypes.push(`["${name}", ${typeInfo.typeName}]`);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return {
|
|
330
|
+
typeName: tupleTypes.join(' | '),
|
|
331
|
+
msgpackTypeName: tupleTypes.join(' | '),
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
case 'vector': {
|
|
336
|
+
const [subtype] = args[0];
|
|
337
|
+
if (subtype === 'unsigned char') {
|
|
338
|
+
return { typeName: 'Uint8Array' };
|
|
339
|
+
}
|
|
340
|
+
const subtypeInfo = this.processSchema(subtype);
|
|
341
|
+
return {
|
|
342
|
+
typeName: `${subtypeInfo.typeName}[]`,
|
|
343
|
+
msgpackTypeName: `${subtypeInfo.msgpackTypeName || subtypeInfo.typeName}[]`,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
case 'alias': {
|
|
348
|
+
const [rawTypeName, msgpackName] = args[0];
|
|
349
|
+
const typeName = pascalCase(rawTypeName);
|
|
350
|
+
let targetType: string;
|
|
351
|
+
|
|
352
|
+
if (msgpackName.startsWith('bin')) {
|
|
353
|
+
targetType = 'Uint8Array';
|
|
354
|
+
} else if (['int', 'unsigned int', 'unsigned short'].includes(msgpackName)) {
|
|
355
|
+
targetType = 'number';
|
|
356
|
+
} else {
|
|
357
|
+
throw new Error(`Unsupported alias type: ${msgpackName}`);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// Create a proper type alias declaration
|
|
361
|
+
return {
|
|
362
|
+
typeName,
|
|
363
|
+
msgpackTypeName: targetType,
|
|
364
|
+
declaration: `export type ${typeName} = ${targetType};`,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
case 'shared_ptr': {
|
|
369
|
+
const [subtype] = args[0];
|
|
370
|
+
return this.processSchema(subtype);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
case 'map': {
|
|
374
|
+
const [keyType, valueType] = args[0];
|
|
375
|
+
const keyInfo = this.processSchema(keyType);
|
|
376
|
+
const valueInfo = this.processSchema(valueType);
|
|
377
|
+
return {
|
|
378
|
+
typeName: `Record<${keyInfo.typeName}, ${valueInfo.typeName}>`,
|
|
379
|
+
msgpackTypeName: `Record<${keyInfo.msgpackTypeName || keyInfo.typeName}, ${valueInfo.msgpackTypeName || valueInfo.typeName}>`,
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
default:
|
|
384
|
+
throw new Error(`Unsupported array schema type: ${type}`);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
private processPrimitiveSchema(schema: string): TypeInfo {
|
|
389
|
+
switch (schema) {
|
|
390
|
+
case 'bool':
|
|
391
|
+
return { typeName: 'boolean' };
|
|
392
|
+
case 'int':
|
|
393
|
+
case 'unsigned int':
|
|
394
|
+
case 'unsigned short':
|
|
395
|
+
case 'unsigned long':
|
|
396
|
+
case 'double':
|
|
397
|
+
return { typeName: 'number' };
|
|
398
|
+
case 'string':
|
|
399
|
+
return { typeName: 'string' };
|
|
400
|
+
case 'bin32':
|
|
401
|
+
return { typeName: 'Uint8Array' };
|
|
402
|
+
default:
|
|
403
|
+
return { typeName: pascalCase(schema) };
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
private processObjectSchema(schema: ObjectSchema): TypeInfo {
|
|
408
|
+
const typeName = pascalCase(schema.__typename as string);
|
|
409
|
+
const msgpackTypeName = 'Msgpack' + typeName;
|
|
410
|
+
|
|
411
|
+
const declaration = this.generateInterfaces(typeName, schema);
|
|
412
|
+
const toMethod = this.generateToMethod(typeName, schema);
|
|
413
|
+
const fromMethod = this.generateFromMethod(typeName, schema);
|
|
414
|
+
|
|
415
|
+
return {
|
|
416
|
+
typeName,
|
|
417
|
+
msgpackTypeName,
|
|
418
|
+
declaration,
|
|
419
|
+
toMethod,
|
|
420
|
+
fromMethod,
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
private getOrCreateEmptyType(typeName: string): TypeInfo {
|
|
425
|
+
const key = `empty_${typeName}`;
|
|
426
|
+
if (this.typeCache.has(key)) {
|
|
427
|
+
return this.typeCache.get(key)!;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const typeInfo: TypeInfo = {
|
|
431
|
+
typeName,
|
|
432
|
+
msgpackTypeName: 'Msgpack' + typeName,
|
|
433
|
+
declaration: `export interface ${typeName} {}\n\ninterface Msgpack${typeName} {}`,
|
|
434
|
+
toMethod: `function to${typeName}(o: Msgpack${typeName}): ${typeName} {\n return {};\n}`,
|
|
435
|
+
fromMethod: `function from${typeName}(o: ${typeName}): Msgpack${typeName} {\n return {};\n}`,
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
this.typeCache.set(key, typeInfo);
|
|
439
|
+
return typeInfo;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
private generateInterfaces(name: string, schema: ObjectSchema): string {
|
|
443
|
+
const publicInterface = this.generatePublicInterface(name, schema);
|
|
444
|
+
const msgpackInterface = this.generateMsgpackInterface(name, schema);
|
|
445
|
+
return publicInterface + '\n\n' + msgpackInterface;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
private generatePublicInterface(name: string, schema: ObjectSchema): string {
|
|
449
|
+
let result = `export interface ${name} {\n`;
|
|
450
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
451
|
+
if (key === '__typename') continue;
|
|
452
|
+
const typeInfo = this.processSchema(value);
|
|
453
|
+
|
|
454
|
+
// Track type usage
|
|
455
|
+
this.trackTypeUsage(typeInfo.typeName);
|
|
456
|
+
|
|
457
|
+
result += ` ${camelCase(key)}: ${typeInfo.typeName};\n`;
|
|
458
|
+
}
|
|
459
|
+
result += '}';
|
|
460
|
+
return result;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
private generateMsgpackInterface(name: string, schema: ObjectSchema): string {
|
|
464
|
+
let result = `interface Msgpack${name} {\n`;
|
|
465
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
466
|
+
if (key === '__typename') continue;
|
|
467
|
+
const typeInfo = this.processSchema(value);
|
|
468
|
+
result += ` ${key}: ${typeInfo.msgpackTypeName || typeInfo.typeName};\n`;
|
|
469
|
+
}
|
|
470
|
+
result += '}';
|
|
471
|
+
return result;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
private generateToMethod(name: string, schema: ObjectSchema): string {
|
|
475
|
+
const fields = Object.entries(schema).filter(([key]) => key !== '__typename');
|
|
476
|
+
|
|
477
|
+
if (fields.length === 0) {
|
|
478
|
+
return `function to${name}(o: Msgpack${name}): ${name} {\n return {};\n}`;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
const checks = fields.map(([key]) =>
|
|
482
|
+
` if (o.${key} === undefined) { throw new Error("Expected ${key} in ${name} deserialization"); }`
|
|
483
|
+
).join('\n');
|
|
484
|
+
|
|
485
|
+
const conversions = fields.map(([key, value]) => {
|
|
486
|
+
const typeInfo = this.processSchema(value);
|
|
487
|
+
const converter = this.generateConverter(typeInfo, `o.${key}`, 'to');
|
|
488
|
+
return ` ${camelCase(key)}: ${converter},`;
|
|
489
|
+
}).join('\n');
|
|
490
|
+
|
|
491
|
+
return `function to${name}(o: Msgpack${name}): ${name} {
|
|
492
|
+
${checks};
|
|
493
|
+
return {
|
|
494
|
+
${conversions}
|
|
495
|
+
};
|
|
496
|
+
}`;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
private generateFromMethod(name: string, schema: ObjectSchema): string {
|
|
500
|
+
const fields = Object.entries(schema).filter(([key]) => key !== '__typename');
|
|
501
|
+
|
|
502
|
+
if (fields.length === 0) {
|
|
503
|
+
return `function from${name}(o: ${name}): Msgpack${name} {\n return {};\n}`;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
const checks = fields.map(([key]) =>
|
|
507
|
+
` if (o.${camelCase(key)} === undefined) { throw new Error("Expected ${camelCase(key)} in ${name} serialization"); }`
|
|
508
|
+
).join('\n');
|
|
509
|
+
|
|
510
|
+
const conversions = fields.map(([key, value]) => {
|
|
511
|
+
const typeInfo = this.processSchema(value);
|
|
512
|
+
const converter = this.generateConverter(typeInfo, `o.${camelCase(key)}`, 'from');
|
|
513
|
+
return ` ${key}: ${converter},`;
|
|
514
|
+
}).join('\n');
|
|
515
|
+
|
|
516
|
+
return `function from${name}(o: ${name}): Msgpack${name} {
|
|
517
|
+
${checks};
|
|
518
|
+
return {
|
|
519
|
+
${conversions}
|
|
520
|
+
};
|
|
521
|
+
}`;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
private generateConverter(typeInfo: TypeInfo, value: string, direction: 'to' | 'from'): string {
|
|
525
|
+
// Handle arrays/tuples
|
|
526
|
+
if (typeInfo.typeName.includes('[]') || typeInfo.typeName.includes('Tuple<')) {
|
|
527
|
+
const elementType = typeInfo.typeName.match(/^(.+)\[\]$/) || typeInfo.typeName.match(/^Tuple<(.+),/);
|
|
528
|
+
if (elementType) {
|
|
529
|
+
const isTuple = typeInfo.typeName.includes('Tuple<');
|
|
530
|
+
const mapFn = isTuple ? 'mapTuple' : 'map';
|
|
531
|
+
return `${value}.${mapFn}((v: any) => v)`; // Simplified for now
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// Handle custom types
|
|
536
|
+
if (typeInfo.declaration) {
|
|
537
|
+
return `${direction}${typeInfo.typeName}(${value})`;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
return value;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
private generateImports(): string[] {
|
|
544
|
+
const imports: string[] = [];
|
|
545
|
+
|
|
546
|
+
// Base imports
|
|
547
|
+
if (this.config.imports) {
|
|
548
|
+
imports.push(...this.config.imports);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// For API modes, import from api_types
|
|
552
|
+
if (this.config.mode !== 'types') {
|
|
553
|
+
const neededImports = new Set<string>();
|
|
554
|
+
|
|
555
|
+
// Add types and conversion functions from function metadata
|
|
556
|
+
for (const metadata of this.functionMetadata) {
|
|
557
|
+
neededImports.add(metadata.commandType);
|
|
558
|
+
neededImports.add(metadata.responseType);
|
|
559
|
+
neededImports.add(`from${metadata.commandType}`);
|
|
560
|
+
neededImports.add(`to${metadata.responseType}`);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// Add referenced types
|
|
564
|
+
for (const type of this.referencedTypes) {
|
|
565
|
+
neededImports.add(type);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// Add BbApiBase interface
|
|
569
|
+
neededImports.add('BbApiBase');
|
|
570
|
+
|
|
571
|
+
if (neededImports.size > 0) {
|
|
572
|
+
const sortedImports = Array.from(neededImports).sort();
|
|
573
|
+
imports.push(`import { ${sortedImports.join(', ')} } from './api_types.js';`);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
return imports;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
private generateBbApiBaseInterface(): string {
|
|
581
|
+
const methods = this.functionMetadata.map(m =>
|
|
582
|
+
` ${m.name}(command: ${m.commandType}): Promise<${m.responseType}>;`
|
|
583
|
+
).join('\n');
|
|
584
|
+
|
|
585
|
+
return `export interface BbApiBase {
|
|
586
|
+
${methods}
|
|
587
|
+
destroy(): Promise<void>;
|
|
588
|
+
}`;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
private generateApiClass(): string {
|
|
592
|
+
const className = this.getApiClassName();
|
|
593
|
+
const methods = this.functionMetadata.map(m => this.generateApiMethod(m)).join('\n\n');
|
|
594
|
+
|
|
595
|
+
if (this.config.mode === 'native') {
|
|
596
|
+
return this.generateNativeApiClass(methods);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
// For sync API, don't implement BbApiBase since methods are synchronous
|
|
600
|
+
const implementsClause = this.config.mode === 'sync' ? '' : ' implements BbApiBase';
|
|
601
|
+
|
|
602
|
+
const msgpackCallHelper = `${this.config.mode === 'async' ? 'async ' : ''}function msgpackCall(wasm: ${this.getWasmType()}, cbind: string, input: any[]) {` +
|
|
603
|
+
` const inputBuffer = new Encoder({ useRecords: false }).pack(input);` +
|
|
604
|
+
` const encodedResult = ${this.config.mode === 'async' ? 'await ' : ''}wasm.cbindCall(cbind, inputBuffer);` +
|
|
605
|
+
` return new Decoder({ useRecords: false }).unpack(encodedResult);` +
|
|
606
|
+
`}\n`;
|
|
607
|
+
return (
|
|
608
|
+
msgpackCallHelper +
|
|
609
|
+
`export class ${className}${implementsClause} {
|
|
610
|
+
constructor(protected wasm: ${this.getWasmType()}) {}
|
|
611
|
+
|
|
612
|
+
${methods}
|
|
613
|
+
|
|
614
|
+
destroy(): Promise<void> {
|
|
615
|
+
return this.wasm.destroy();
|
|
616
|
+
}
|
|
617
|
+
}`
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
private getApiClassName(): string {
|
|
622
|
+
switch (this.config.mode) {
|
|
623
|
+
case 'sync': return 'SyncApi';
|
|
624
|
+
case 'async': return 'AsyncApi';
|
|
625
|
+
case 'native': return 'NativeApi';
|
|
626
|
+
default: throw new Error(`Invalid mode: ${this.config.mode}`);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
private getWasmType(): string {
|
|
631
|
+
switch (this.config.mode) {
|
|
632
|
+
case 'sync': return 'BarretenbergWasmMain';
|
|
633
|
+
case 'async': return 'BarretenbergWasmMainWorker';
|
|
634
|
+
default: return '';
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
private generateApiMethod(metadata: FunctionMetadata): string {
|
|
639
|
+
const { name, commandType, responseType } = metadata;
|
|
640
|
+
|
|
641
|
+
if (this.config.mode === 'native') {
|
|
642
|
+
return ` ${name}(command: ${commandType}): Promise<${responseType}> {
|
|
643
|
+
const msgpackCommand = from${commandType}(command);
|
|
644
|
+
return this.sendCommand(['${metadata.commandType}', msgpackCommand]).then(([variantName, result]: [string, any]) => {
|
|
645
|
+
if (variantName !== '${responseType}') {
|
|
646
|
+
throw new Error(\`Expected variant name '${responseType}' but got '\${variantName}'\`);
|
|
647
|
+
}
|
|
648
|
+
return to${responseType}(result);
|
|
649
|
+
});
|
|
650
|
+
}`;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// For async mode, queue immediately and return promise
|
|
654
|
+
if (this.config.mode === 'async') {
|
|
655
|
+
return ` ${name}(command: ${commandType}): Promise<${responseType}> {
|
|
656
|
+
const msgpackCommand = from${commandType}(command);
|
|
657
|
+
return msgpackCall(this.wasm, 'bbapi', [["${capitalize(name)}", msgpackCommand]]).then(([variantName, result]: [string, any]) => {
|
|
658
|
+
if (variantName !== '${responseType}') {
|
|
659
|
+
throw new Error(\`Expected variant name '${responseType}' but got '\${variantName}'\`);
|
|
660
|
+
}
|
|
661
|
+
return to${responseType}(result);
|
|
662
|
+
});
|
|
663
|
+
}`;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
// For sync mode, keep the synchronous behavior
|
|
667
|
+
return ` ${name}(command: ${commandType}): ${responseType} {
|
|
668
|
+
const msgpackCommand = from${commandType}(command);
|
|
669
|
+
const [variantName, result] = msgpackCall(this.wasm, 'bbapi', [["${capitalize(name)}", msgpackCommand]]);
|
|
670
|
+
if (variantName !== '${responseType}') {
|
|
671
|
+
throw new Error(\`Expected variant name '${responseType}' but got '\${variantName}'\`);
|
|
672
|
+
}
|
|
673
|
+
return to${responseType}(result);
|
|
674
|
+
}`;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
private generateNativeApiClass(methods: string): string {
|
|
678
|
+
return `interface NativeApiRequest {
|
|
679
|
+
resolve: (value: any) => void;
|
|
680
|
+
reject: (error: any) => void;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
class StreamBuffer {
|
|
684
|
+
private buffer = Buffer.alloc(0);
|
|
685
|
+
private expectedLength: number | null = null;
|
|
686
|
+
|
|
687
|
+
addData(data: Buffer): Buffer[] {
|
|
688
|
+
// Create buffer to grow as needed
|
|
689
|
+
const newBuffer = Buffer.allocUnsafe(this.buffer.length + data.length);
|
|
690
|
+
this.buffer.copy(newBuffer, 0);
|
|
691
|
+
data.copy(newBuffer, this.buffer.length);
|
|
692
|
+
this.buffer = newBuffer;
|
|
693
|
+
|
|
694
|
+
const messages: Buffer[] = [];
|
|
695
|
+
|
|
696
|
+
while (true) {
|
|
697
|
+
if (this.expectedLength === null) {
|
|
698
|
+
if (this.buffer.length < 4) break;
|
|
699
|
+
this.expectedLength = this.buffer.readUInt32LE(0);
|
|
700
|
+
this.buffer = this.buffer.subarray(4);
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
if (this.buffer.length < this.expectedLength) break;
|
|
704
|
+
|
|
705
|
+
// Extract complete message
|
|
706
|
+
const messageBuffer = this.buffer.subarray(0, this.expectedLength);
|
|
707
|
+
messages.push(messageBuffer);
|
|
708
|
+
this.buffer = this.buffer.subarray(this.expectedLength);
|
|
709
|
+
this.expectedLength = null;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
return messages;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
export class NativeApi implements BbApiBase {
|
|
717
|
+
private decoder = new Decoder({ useRecords: false });
|
|
718
|
+
private encoder = new Encoder({ useRecords: false });
|
|
719
|
+
private pendingRequests: NativeApiRequest[] = [];
|
|
720
|
+
|
|
721
|
+
private constructor(private proc: ChildProcess) {}
|
|
722
|
+
|
|
723
|
+
static async new(bbPath = 'bb', logger = console.log): Promise<NativeApi> {
|
|
724
|
+
const proc = spawn(bbPath, ['msgpack', 'run'], {
|
|
725
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
if (!proc.stdout || !proc.stdin) {
|
|
729
|
+
throw new Error('Failed to initialize bb process');
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
const api = new NativeApi(proc);
|
|
733
|
+
const streamBuffer = new StreamBuffer();
|
|
734
|
+
|
|
735
|
+
proc.stdout.on('data', (data: Buffer) => {
|
|
736
|
+
const messages = streamBuffer.addData(data);
|
|
737
|
+
|
|
738
|
+
for (const messageBuffer of messages) {
|
|
739
|
+
const pendingRequest = api.pendingRequests.shift();
|
|
740
|
+
if (!pendingRequest) {
|
|
741
|
+
throw new Error('Received response without a pending request');
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
try {
|
|
745
|
+
const decoded = api.decoder.decode(messageBuffer);
|
|
746
|
+
if (!Array.isArray(decoded) || decoded.length !== 2) {
|
|
747
|
+
throw new Error(\`Invalid response format: \${JSON.stringify(decoded)}\`);
|
|
748
|
+
}
|
|
749
|
+
const [variantName, result] = decoded;
|
|
750
|
+
pendingRequest.resolve([variantName, result]);
|
|
751
|
+
} catch (error) {
|
|
752
|
+
pendingRequest.reject(error);
|
|
753
|
+
break;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
proc.stderr.on('data', (data: Buffer) => {
|
|
759
|
+
logger(data.toString().trim());
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
proc.on('error', err => {
|
|
763
|
+
throw new Error(err.message);
|
|
764
|
+
});
|
|
765
|
+
return api;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
private sendCommand(command: any): Promise<any> {
|
|
769
|
+
return new Promise((resolve, reject) => {
|
|
770
|
+
this.pendingRequests.push({ resolve, reject });
|
|
771
|
+
const encoded = this.encoder.encode(command);
|
|
772
|
+
|
|
773
|
+
// Write length prefix (4 bytes, little-endian)
|
|
774
|
+
const lengthBuffer = Buffer.allocUnsafe(4);
|
|
775
|
+
lengthBuffer.writeUInt32LE(encoded.length, 0);
|
|
776
|
+
|
|
777
|
+
// Write length prefix followed by the encoded data
|
|
778
|
+
this.proc.stdin!.write(lengthBuffer);
|
|
779
|
+
this.proc.stdin!.write(encoded);
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
async close(): Promise<void> {
|
|
784
|
+
this.proc.kill();
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
destroy(): Promise<void> {
|
|
788
|
+
return this.close();
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
${methods}
|
|
792
|
+
}`;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
// Factory methods for creating configured compilers
|
|
797
|
+
export function createSharedTypesCompiler(): SchemaCompiler {
|
|
798
|
+
return new SchemaCompiler({
|
|
799
|
+
mode: 'types',
|
|
800
|
+
imports: [],
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
export function createSyncApiCompiler(): SchemaCompiler {
|
|
805
|
+
return new SchemaCompiler({
|
|
806
|
+
mode: 'sync',
|
|
807
|
+
imports: [
|
|
808
|
+
`import { BarretenbergWasmMain } from "../../barretenberg_wasm/barretenberg_wasm_main/index.js";`,
|
|
809
|
+
`import { Decoder, Encoder } from 'msgpackr';`,
|
|
810
|
+
],
|
|
811
|
+
});
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
export function createAsyncApiCompiler(): SchemaCompiler {
|
|
815
|
+
return new SchemaCompiler({
|
|
816
|
+
mode: 'async',
|
|
817
|
+
imports: [
|
|
818
|
+
`import { BarretenbergWasmMainWorker } from "../../barretenberg_wasm/barretenberg_wasm_main/index.js";`,
|
|
819
|
+
`import { Decoder, Encoder } from 'msgpackr';`
|
|
820
|
+
],
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
export function createNativeApiCompiler(): SchemaCompiler {
|
|
825
|
+
return new SchemaCompiler({
|
|
826
|
+
mode: 'native',
|
|
827
|
+
imports: [
|
|
828
|
+
`import { spawn, ChildProcess } from 'child_process';`,
|
|
829
|
+
`import { Decoder, Encoder } from 'msgpackr';`
|
|
830
|
+
],
|
|
831
|
+
});
|
|
832
|
+
}
|