@latticexyz/store 2.2.18-ebe1aea8d4afb690ce1c7c2bcb42dc0f1faf6e77 → 2.2.18
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/dist/chunk-FULF4J63.js +460 -0
- package/dist/{chunk-5YJ4WITG.js.map → chunk-FULF4J63.js.map} +1 -1
- package/dist/chunk-ZBDA5HOY.js +27 -0
- package/dist/{chunk-4TACS4IT.js.map → chunk-ZBDA5HOY.js.map} +1 -1
- package/dist/codegen.js +1005 -210
- package/dist/codegen.js.map +1 -1
- package/dist/index.js +22 -1
- package/dist/internal.js +302 -1
- package/dist/internal.js.map +1 -1
- package/dist/mud.config.js +60 -1
- package/dist/mud.config.js.map +1 -1
- package/package.json +7 -7
- package/dist/chunk-4TACS4IT.js +0 -2
- package/dist/chunk-5YJ4WITG.js +0 -2
package/dist/codegen.js
CHANGED
@@ -1,262 +1,669 @@
|
|
1
|
-
|
1
|
+
// ts/codegen/field.ts
|
2
|
+
import {
|
3
|
+
renderArguments,
|
4
|
+
renderCommonData,
|
5
|
+
renderWithFieldSuffix,
|
6
|
+
renderWithStore
|
7
|
+
} from "@latticexyz/common/codegen";
|
8
|
+
function renderFieldMethods(options) {
|
9
|
+
const storeArgument = options.storeArgument;
|
10
|
+
const { _typedTableId, _typedKeyArgs, _keyTupleDefinition } = renderCommonData(options);
|
11
|
+
let result = "";
|
12
|
+
for (const [schemaIndex, field] of options.fields.entries()) {
|
13
|
+
if (!options.withDynamicFieldMethods && field.isDynamic) {
|
14
|
+
continue;
|
15
|
+
}
|
16
|
+
const _typedFieldName = `${field.typeWithLocation} ${field.name}`;
|
17
|
+
if (options.withGetters) {
|
18
|
+
result += renderWithFieldSuffix(
|
19
|
+
options.withSuffixlessFieldMethods,
|
20
|
+
field.name,
|
21
|
+
(_methodNameSuffix) => renderWithStore(
|
22
|
+
storeArgument,
|
23
|
+
({ _typedStore, _store, _commentSuffix, _methodNamePrefix }) => `
|
2
24
|
/**
|
3
|
-
* @notice Get ${
|
25
|
+
* @notice Get ${field.name}${_commentSuffix}.
|
4
26
|
*/
|
5
|
-
function ${
|
6
|
-
|
7
|
-
|
27
|
+
function ${_methodNamePrefix}get${_methodNameSuffix}(${renderArguments([
|
28
|
+
_typedStore,
|
29
|
+
_typedTableId,
|
30
|
+
_typedKeyArgs
|
31
|
+
])}) internal view returns (${_typedFieldName}) {
|
32
|
+
${_keyTupleDefinition}
|
33
|
+
${field.isDynamic ? `bytes memory _blob = ${_store}.getDynamicField(
|
8
34
|
_tableId,
|
9
35
|
_keyTuple,
|
10
|
-
${
|
11
|
-
)
|
36
|
+
${schemaIndex - options.staticFields.length}
|
37
|
+
);` : `bytes32 _blob = ${_store}.getStaticField(
|
12
38
|
_tableId,
|
13
39
|
_keyTuple,
|
14
|
-
${
|
40
|
+
${schemaIndex},
|
15
41
|
_fieldLayout
|
16
42
|
);`}
|
17
|
-
return ${
|
43
|
+
return ${renderDecodeFieldSingle(field)};
|
18
44
|
}
|
19
|
-
`
|
45
|
+
`
|
46
|
+
)
|
47
|
+
);
|
48
|
+
}
|
49
|
+
result += renderWithFieldSuffix(
|
50
|
+
options.withSuffixlessFieldMethods,
|
51
|
+
field.name,
|
52
|
+
(_methodNameSuffix) => renderWithStore(storeArgument, ({ _typedStore, _store, _commentSuffix, _methodNamePrefix }) => {
|
53
|
+
const externalArguments = renderArguments([_typedStore, _typedTableId, _typedKeyArgs, _typedFieldName]);
|
54
|
+
const setFieldMethod = field.isDynamic ? "setDynamicField" : "setStaticField";
|
55
|
+
const encodeFieldSingle = renderEncodeFieldSingle(field);
|
56
|
+
const internalArguments = field.isDynamic ? `_tableId, _keyTuple, ${schemaIndex - options.staticFields.length}, ${encodeFieldSingle}` : `_tableId, _keyTuple, ${schemaIndex}, ${encodeFieldSingle}, _fieldLayout`;
|
57
|
+
return `
|
20
58
|
/**
|
21
|
-
* @notice Set ${
|
59
|
+
* @notice Set ${field.name}${_commentSuffix}.
|
22
60
|
*/
|
23
|
-
function ${
|
24
|
-
${
|
25
|
-
${
|
61
|
+
function ${_methodNamePrefix}set${_methodNameSuffix}(${externalArguments}) internal {
|
62
|
+
${_keyTupleDefinition}
|
63
|
+
${_store}.${setFieldMethod}(${internalArguments});
|
26
64
|
}
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
65
|
+
`;
|
66
|
+
})
|
67
|
+
);
|
68
|
+
if (field.isDynamic) {
|
69
|
+
const portionData = fieldPortionData(field);
|
70
|
+
const dynamicSchemaIndex = schemaIndex - options.staticFields.length;
|
71
|
+
const { typeWrappingData } = field;
|
72
|
+
if (options.withGetters) {
|
73
|
+
if (typeWrappingData && typeWrappingData.kind === "staticArray") {
|
74
|
+
result += renderWithFieldSuffix(
|
75
|
+
options.withSuffixlessFieldMethods,
|
76
|
+
field.name,
|
77
|
+
(_methodNameSuffix) => `
|
78
|
+
// The length of ${field.name}
|
79
|
+
uint256 constant length${_methodNameSuffix} = ${typeWrappingData.staticLength};
|
80
|
+
`
|
81
|
+
);
|
82
|
+
} else {
|
83
|
+
result += renderWithFieldSuffix(
|
84
|
+
options.withSuffixlessFieldMethods,
|
85
|
+
field.name,
|
86
|
+
(_methodNameSuffix) => renderWithStore(
|
87
|
+
storeArgument,
|
88
|
+
({ _typedStore, _store, _commentSuffix, _methodNamePrefix }) => `
|
31
89
|
/**
|
32
|
-
* @notice Get the length of ${
|
90
|
+
* @notice Get the length of ${field.name}${_commentSuffix}.
|
33
91
|
*/
|
34
|
-
function ${
|
35
|
-
|
36
|
-
|
92
|
+
function ${_methodNamePrefix}length${_methodNameSuffix}(${renderArguments([
|
93
|
+
_typedStore,
|
94
|
+
_typedTableId,
|
95
|
+
_typedKeyArgs
|
96
|
+
])}) internal view returns (uint256) {
|
97
|
+
${_keyTupleDefinition}
|
98
|
+
uint256 _byteLength = ${_store}.getDynamicFieldLength(_tableId, _keyTuple, ${dynamicSchemaIndex});
|
37
99
|
unchecked {
|
38
|
-
return _byteLength / ${
|
100
|
+
return _byteLength / ${portionData.elementLength};
|
39
101
|
}
|
40
102
|
}
|
41
|
-
`
|
103
|
+
`
|
104
|
+
)
|
105
|
+
);
|
106
|
+
}
|
107
|
+
result += renderWithFieldSuffix(
|
108
|
+
options.withSuffixlessFieldMethods,
|
109
|
+
field.name,
|
110
|
+
(_methodNameSuffix) => renderWithStore(
|
111
|
+
storeArgument,
|
112
|
+
({ _typedStore, _store, _commentSuffix, _methodNamePrefix }) => `
|
42
113
|
/**
|
43
|
-
* @notice Get an item of ${
|
114
|
+
* @notice Get an item of ${field.name}${_commentSuffix}.
|
44
115
|
* @dev Reverts with Store_IndexOutOfBounds if \`_index\` is out of bounds for the array.
|
45
116
|
*/
|
46
|
-
function ${
|
47
|
-
|
117
|
+
function ${_methodNamePrefix}getItem${_methodNameSuffix}(${renderArguments([
|
118
|
+
_typedStore,
|
119
|
+
_typedTableId,
|
120
|
+
_typedKeyArgs,
|
121
|
+
"uint256 _index"
|
122
|
+
])}) internal view returns (${portionData.typeWithLocation}) {
|
123
|
+
${_keyTupleDefinition}
|
48
124
|
|
49
|
-
${
|
50
|
-
|
51
|
-
|
52
|
-
uint256
|
125
|
+
${// If the index is within the static length,
|
126
|
+
// but ahead of the dynamic length, return zero
|
127
|
+
typeWrappingData && typeWrappingData.kind === "staticArray" && field.arrayElement ? `
|
128
|
+
uint256 _byteLength = ${_store}.getDynamicFieldLength(_tableId, _keyTuple, ${dynamicSchemaIndex});
|
129
|
+
uint256 dynamicLength = _byteLength / ${portionData.elementLength};
|
130
|
+
uint256 staticLength = ${typeWrappingData.staticLength};
|
53
131
|
|
54
132
|
if (_index < staticLength && _index >= dynamicLength) {
|
55
|
-
return ${
|
56
|
-
}
|
133
|
+
return ${renderCastStaticBytesToType(field.arrayElement, `bytes${field.arrayElement.staticByteLength}(new bytes(0))`)};
|
134
|
+
}` : ``}
|
57
135
|
|
58
136
|
unchecked {
|
59
|
-
bytes memory _blob = ${
|
137
|
+
bytes memory _blob = ${_store}.getDynamicFieldSlice(
|
60
138
|
_tableId,
|
61
139
|
_keyTuple,
|
62
|
-
${
|
63
|
-
_index * ${
|
64
|
-
(_index + 1) * ${
|
140
|
+
${dynamicSchemaIndex},
|
141
|
+
_index * ${portionData.elementLength},
|
142
|
+
(_index + 1) * ${portionData.elementLength}
|
65
143
|
);
|
66
|
-
return ${
|
144
|
+
return ${portionData.decoded};
|
67
145
|
}
|
68
146
|
}
|
69
|
-
`
|
147
|
+
`
|
148
|
+
)
|
149
|
+
);
|
150
|
+
}
|
151
|
+
if (!typeWrappingData || typeWrappingData.kind !== "staticArray") {
|
152
|
+
result += renderWithFieldSuffix(
|
153
|
+
options.withSuffixlessFieldMethods,
|
154
|
+
field.name,
|
155
|
+
(_methodNameSuffix) => renderWithStore(
|
156
|
+
storeArgument,
|
157
|
+
({ _typedStore, _store, _commentSuffix, _methodNamePrefix }) => `
|
70
158
|
/**
|
71
|
-
* @notice Push ${
|
159
|
+
* @notice Push ${portionData.title} to ${field.name}${_commentSuffix}.
|
72
160
|
*/
|
73
|
-
function ${
|
74
|
-
|
75
|
-
|
161
|
+
function ${_methodNamePrefix}push${_methodNameSuffix}(${renderArguments([
|
162
|
+
_typedStore,
|
163
|
+
_typedTableId,
|
164
|
+
_typedKeyArgs,
|
165
|
+
`${portionData.typeWithLocation} ${portionData.name}`
|
166
|
+
])}) internal {
|
167
|
+
${_keyTupleDefinition}
|
168
|
+
${_store}.pushToDynamicField(_tableId, _keyTuple, ${dynamicSchemaIndex}, ${portionData.encoded});
|
76
169
|
}
|
77
|
-
`
|
170
|
+
`
|
171
|
+
)
|
172
|
+
);
|
173
|
+
result += renderWithFieldSuffix(
|
174
|
+
options.withSuffixlessFieldMethods,
|
175
|
+
field.name,
|
176
|
+
(_methodNameSuffix) => renderWithStore(
|
177
|
+
storeArgument,
|
178
|
+
({ _typedStore, _store, _commentSuffix, _methodNamePrefix }) => `
|
78
179
|
/**
|
79
|
-
* @notice Pop ${
|
180
|
+
* @notice Pop ${portionData.title} from ${field.name}${_commentSuffix}.
|
80
181
|
*/
|
81
|
-
function ${
|
82
|
-
|
83
|
-
|
182
|
+
function ${_methodNamePrefix}pop${_methodNameSuffix}(${renderArguments([
|
183
|
+
_typedStore,
|
184
|
+
_typedTableId,
|
185
|
+
_typedKeyArgs
|
186
|
+
])}) internal {
|
187
|
+
${_keyTupleDefinition}
|
188
|
+
${_store}.popFromDynamicField(_tableId, _keyTuple, ${dynamicSchemaIndex}, ${portionData.elementLength});
|
84
189
|
}
|
85
|
-
`
|
190
|
+
`
|
191
|
+
)
|
192
|
+
);
|
193
|
+
}
|
194
|
+
result += renderWithFieldSuffix(
|
195
|
+
options.withSuffixlessFieldMethods,
|
196
|
+
field.name,
|
197
|
+
(_methodNameSuffix) => renderWithStore(storeArgument, ({ _typedStore, _store, _commentSuffix, _methodNamePrefix }) => {
|
198
|
+
const externalArguments = renderArguments([
|
199
|
+
_typedStore,
|
200
|
+
_typedTableId,
|
201
|
+
_typedKeyArgs,
|
202
|
+
"uint256 _index",
|
203
|
+
`${portionData.typeWithLocation} ${portionData.name}`
|
204
|
+
]);
|
205
|
+
const internalArguments = `
|
86
206
|
_tableId,
|
87
207
|
_keyTuple,
|
88
|
-
${
|
89
|
-
uint40(_index * ${
|
208
|
+
${dynamicSchemaIndex},
|
209
|
+
uint40(_index * ${portionData.elementLength}),
|
90
210
|
uint40(_encoded.length),
|
91
211
|
_encoded
|
92
|
-
`;
|
212
|
+
`;
|
213
|
+
return `
|
93
214
|
/**
|
94
|
-
* @notice Update ${
|
215
|
+
* @notice Update ${portionData.title} of ${field.name}${_commentSuffix} at \`_index\`.
|
95
216
|
*/
|
96
|
-
function ${
|
97
|
-
${
|
217
|
+
function ${_methodNamePrefix}update${_methodNameSuffix}(${externalArguments}) internal {
|
218
|
+
${_keyTupleDefinition}
|
98
219
|
unchecked {
|
99
|
-
bytes memory _encoded = ${
|
100
|
-
${
|
220
|
+
bytes memory _encoded = ${portionData.encoded};
|
221
|
+
${_store}.spliceDynamicData(${internalArguments});
|
101
222
|
}
|
102
223
|
}
|
103
|
-
|
104
|
-
|
105
|
-
|
224
|
+
`;
|
225
|
+
})
|
226
|
+
);
|
227
|
+
}
|
228
|
+
}
|
229
|
+
return result;
|
230
|
+
}
|
231
|
+
function renderEncodeFieldSingle(field) {
|
232
|
+
let func;
|
233
|
+
if (field.arrayElement) {
|
234
|
+
func = "EncodeArray.encode";
|
235
|
+
} else if (field.isDynamic) {
|
236
|
+
func = "bytes";
|
237
|
+
} else {
|
238
|
+
func = "abi.encodePacked";
|
239
|
+
}
|
240
|
+
return `${func}(${field.typeUnwrap}(${field.name}))`;
|
241
|
+
}
|
242
|
+
function renderDecodeValueType(field, offset) {
|
243
|
+
const { staticByteLength } = field;
|
244
|
+
const innerSlice = `Bytes.getBytes${staticByteLength}(_blob, ${offset})`;
|
245
|
+
return renderCastStaticBytesToType(field, innerSlice);
|
246
|
+
}
|
247
|
+
function renderCastStaticBytesToType(field, staticBytes) {
|
248
|
+
const { staticByteLength, internalTypeId } = field;
|
249
|
+
const bits = staticByteLength * 8;
|
250
|
+
let result;
|
251
|
+
if (internalTypeId.match(/^uint\d{1,3}$/) || internalTypeId === "address") {
|
252
|
+
result = `${internalTypeId}(${staticBytes})`;
|
253
|
+
} else if (internalTypeId.match(/^int\d{1,3}$/)) {
|
254
|
+
result = `${internalTypeId}(uint${bits}(${staticBytes}))`;
|
255
|
+
} else if (internalTypeId.match(/^bytes\d{1,2}$/)) {
|
256
|
+
result = staticBytes;
|
257
|
+
} else if (internalTypeId === "bool") {
|
258
|
+
result = `_toBool(uint8(${staticBytes}))`;
|
259
|
+
} else {
|
260
|
+
throw new Error(`Unknown value type id ${internalTypeId}`);
|
261
|
+
}
|
262
|
+
return `${field.typeWrap}(${result})`;
|
263
|
+
}
|
264
|
+
function fieldPortionData(field) {
|
265
|
+
if (field.arrayElement) {
|
266
|
+
const name = "_element";
|
267
|
+
const elementFieldData = { ...field.arrayElement, arrayElement: void 0, name };
|
268
|
+
return {
|
269
|
+
typeWithLocation: field.arrayElement.typeWithLocation,
|
270
|
+
name,
|
271
|
+
encoded: renderEncodeFieldSingle(elementFieldData),
|
272
|
+
decoded: renderDecodeFieldSingle(elementFieldData),
|
273
|
+
title: "an element",
|
274
|
+
elementLength: field.arrayElement.staticByteLength
|
275
|
+
};
|
276
|
+
} else {
|
277
|
+
const name = "_slice";
|
278
|
+
const elementFieldData = { ...field, name };
|
279
|
+
return {
|
280
|
+
typeWithLocation: `${field.typeId} memory`,
|
281
|
+
name,
|
282
|
+
encoded: renderEncodeFieldSingle(elementFieldData),
|
283
|
+
decoded: renderDecodeFieldSingle(elementFieldData),
|
284
|
+
title: "a slice",
|
285
|
+
elementLength: 1
|
286
|
+
};
|
287
|
+
}
|
288
|
+
}
|
289
|
+
function renderDecodeFieldSingle(field) {
|
290
|
+
const { isDynamic, arrayElement } = field;
|
291
|
+
if (arrayElement) {
|
292
|
+
return `${field.typeWrap}(
|
293
|
+
SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_${arrayElement.internalTypeId}()
|
294
|
+
)`;
|
295
|
+
} else if (isDynamic) {
|
296
|
+
return `${field.typeWrap}(${field.internalTypeId}(_blob))`;
|
297
|
+
} else {
|
298
|
+
return renderCastStaticBytesToType(field, `bytes${field.staticByteLength}(_blob)`);
|
299
|
+
}
|
300
|
+
}
|
301
|
+
|
302
|
+
// ts/codegen/record.ts
|
303
|
+
import {
|
304
|
+
renderArguments as renderArguments2,
|
305
|
+
renderCommonData as renderCommonData2,
|
306
|
+
renderList,
|
307
|
+
renderWithStore as renderWithStore2
|
308
|
+
} from "@latticexyz/common/codegen";
|
309
|
+
function renderRecordMethods(options) {
|
310
|
+
const { structName, storeArgument } = options;
|
311
|
+
const { _typedTableId, _typedKeyArgs, _keyTupleDefinition } = renderCommonData2(options);
|
312
|
+
let result = "";
|
313
|
+
if (options.withGetters) {
|
314
|
+
result += renderWithStore2(
|
315
|
+
storeArgument,
|
316
|
+
({ _typedStore, _store, _commentSuffix, _methodNamePrefix }) => `
|
106
317
|
/**
|
107
|
-
* @notice Get the full data${
|
318
|
+
* @notice Get the full data${_commentSuffix}.
|
108
319
|
*/
|
109
|
-
function ${
|
110
|
-
|
320
|
+
function ${_methodNamePrefix}get(${renderArguments2([
|
321
|
+
_typedStore,
|
322
|
+
_typedTableId,
|
323
|
+
_typedKeyArgs
|
324
|
+
])}) internal view returns (${renderDecodedRecord(options)}) {
|
325
|
+
${_keyTupleDefinition}
|
111
326
|
|
112
327
|
(
|
113
328
|
bytes memory _staticData,
|
114
329
|
EncodedLengths _encodedLengths,
|
115
330
|
bytes memory _dynamicData
|
116
|
-
) = ${
|
331
|
+
) = ${_store}.getRecord(_tableId, _keyTuple, _fieldLayout);
|
117
332
|
return decode(_staticData, _encodedLengths, _dynamicData);
|
118
333
|
}
|
119
|
-
`
|
334
|
+
`
|
335
|
+
);
|
336
|
+
}
|
337
|
+
result += renderWithStore2(
|
338
|
+
storeArgument,
|
339
|
+
({ _typedStore, _store, _commentSuffix, _methodNamePrefix, _useExplicitFieldLayout }) => {
|
340
|
+
const externalArguments = renderArguments2([
|
341
|
+
_typedStore,
|
342
|
+
_typedTableId,
|
343
|
+
_typedKeyArgs,
|
344
|
+
renderArguments2(options.fields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`))
|
345
|
+
]);
|
346
|
+
const internalArguments = "_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData" + (_useExplicitFieldLayout ? ", _fieldLayout" : "");
|
347
|
+
return `
|
120
348
|
/**
|
121
|
-
* @notice Set the full data using individual values${
|
349
|
+
* @notice Set the full data using individual values${_commentSuffix}.
|
122
350
|
*/
|
123
|
-
function ${
|
124
|
-
${
|
351
|
+
function ${_methodNamePrefix}set(${externalArguments}) internal {
|
352
|
+
${renderRecordData(options)}
|
125
353
|
|
126
|
-
${
|
354
|
+
${_keyTupleDefinition}
|
127
355
|
|
128
|
-
${
|
356
|
+
${_store}.setRecord(${internalArguments});
|
129
357
|
}
|
130
|
-
|
358
|
+
`;
|
359
|
+
}
|
360
|
+
);
|
361
|
+
if (structName !== void 0) {
|
362
|
+
result += renderWithStore2(
|
363
|
+
storeArgument,
|
364
|
+
({ _typedStore, _store, _commentSuffix, _methodNamePrefix, _useExplicitFieldLayout }) => {
|
365
|
+
const externalArguments = renderArguments2([
|
366
|
+
_typedStore,
|
367
|
+
_typedTableId,
|
368
|
+
_typedKeyArgs,
|
369
|
+
`${structName} memory _table`
|
370
|
+
]);
|
371
|
+
const internalArguments = "_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData" + (_useExplicitFieldLayout ? ", _fieldLayout" : "");
|
372
|
+
return `
|
131
373
|
/**
|
132
|
-
* @notice Set the full data using the data struct${
|
374
|
+
* @notice Set the full data using the data struct${_commentSuffix}.
|
133
375
|
*/
|
134
|
-
function ${
|
135
|
-
${
|
376
|
+
function ${_methodNamePrefix}set(${externalArguments}) internal {
|
377
|
+
${renderRecordData(options, "_table.")}
|
136
378
|
|
137
|
-
${
|
379
|
+
${_keyTupleDefinition}
|
138
380
|
|
139
|
-
${
|
381
|
+
${_store}.setRecord(${internalArguments});
|
140
382
|
}
|
141
|
-
|
383
|
+
`;
|
384
|
+
}
|
385
|
+
);
|
386
|
+
}
|
387
|
+
result += renderDecodeFunctions(options);
|
388
|
+
return result;
|
389
|
+
}
|
390
|
+
function renderRecordData(options, namePrefix = "") {
|
391
|
+
let result = "";
|
392
|
+
if (options.staticFields.length > 0) {
|
393
|
+
result += `
|
142
394
|
bytes memory _staticData = encodeStatic(
|
143
|
-
${
|
395
|
+
${renderArguments2(options.staticFields.map(({ name }) => `${namePrefix}${name}`))}
|
144
396
|
);
|
145
|
-
|
397
|
+
`;
|
398
|
+
} else {
|
399
|
+
result += `bytes memory _staticData;`;
|
400
|
+
}
|
401
|
+
if (options.dynamicFields.length > 0) {
|
402
|
+
result += `
|
146
403
|
EncodedLengths _encodedLengths = encodeLengths(
|
147
|
-
${
|
404
|
+
${renderArguments2(options.dynamicFields.map(({ name }) => `${namePrefix}${name}`))}
|
148
405
|
);
|
149
406
|
bytes memory _dynamicData = encodeDynamic(
|
150
|
-
${
|
407
|
+
${renderArguments2(options.dynamicFields.map(({ name }) => `${namePrefix}${name}`))}
|
151
408
|
);
|
152
|
-
|
409
|
+
`;
|
410
|
+
} else {
|
411
|
+
result += `
|
153
412
|
EncodedLengths _encodedLengths;
|
154
413
|
bytes memory _dynamicData;
|
155
|
-
|
414
|
+
`;
|
415
|
+
}
|
416
|
+
return result;
|
417
|
+
}
|
418
|
+
function renderDeleteRecordMethods(options) {
|
419
|
+
const { storeArgument } = options;
|
420
|
+
const { _typedTableId, _typedKeyArgs, _keyTupleDefinition } = renderCommonData2(options);
|
421
|
+
return renderWithStore2(
|
422
|
+
storeArgument,
|
423
|
+
({ _typedStore, _store, _commentSuffix, _methodNamePrefix, _useExplicitFieldLayout }) => {
|
424
|
+
const externalArguments = renderArguments2([_typedStore, _typedTableId, _typedKeyArgs]);
|
425
|
+
const internalArguments = "_tableId, _keyTuple" + (_useExplicitFieldLayout ? ", _fieldLayout" : "");
|
426
|
+
return `
|
156
427
|
/**
|
157
|
-
* @notice Delete all data for given keys${
|
428
|
+
* @notice Delete all data for given keys${_commentSuffix}.
|
158
429
|
*/
|
159
|
-
function ${
|
160
|
-
${
|
161
|
-
${
|
430
|
+
function ${_methodNamePrefix}deleteRecord(${externalArguments}) internal {
|
431
|
+
${_keyTupleDefinition}
|
432
|
+
${_store}.deleteRecord(${internalArguments});
|
162
433
|
}
|
163
|
-
|
434
|
+
`;
|
435
|
+
}
|
436
|
+
);
|
437
|
+
}
|
438
|
+
function renderDecodeFunctions({ structName, fields, staticFields, dynamicFields }) {
|
439
|
+
const renderedDecodedRecord = structName ? `${structName} memory _table` : renderArguments2(fields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`));
|
440
|
+
const fieldNamePrefix = structName ? "_table." : "";
|
441
|
+
const staticOffsets = staticFields.map(() => 0);
|
442
|
+
let _acc = 0;
|
443
|
+
for (const [index, field] of staticFields.entries()) {
|
444
|
+
staticOffsets[index] = _acc;
|
445
|
+
_acc += field.staticByteLength;
|
446
|
+
}
|
447
|
+
let result = "";
|
448
|
+
if (staticFields.length > 0) {
|
449
|
+
result += `
|
164
450
|
/**
|
165
451
|
* @notice Decode the tightly packed blob of static data using this table's field layout.
|
166
452
|
*/
|
167
|
-
function decodeStatic(bytes memory _blob) internal pure returns (${
|
168
|
-
|
169
|
-
|
170
|
-
|
453
|
+
function decodeStatic(bytes memory _blob) internal pure returns (${renderArguments2(
|
454
|
+
staticFields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`)
|
455
|
+
)}) {
|
456
|
+
${renderList(
|
457
|
+
staticFields,
|
458
|
+
(field, index) => `
|
459
|
+
${field.name} = ${renderDecodeValueType(field, staticOffsets[index])};
|
460
|
+
`
|
461
|
+
)}
|
171
462
|
}
|
172
|
-
|
463
|
+
`;
|
464
|
+
}
|
465
|
+
if (dynamicFields.length > 0) {
|
466
|
+
result += `
|
173
467
|
/**
|
174
468
|
* @notice Decode the tightly packed blob of dynamic data using the encoded lengths.
|
175
469
|
*/
|
176
|
-
function decodeDynamic(EncodedLengths _encodedLengths, bytes memory _blob) internal pure returns (${
|
177
|
-
|
470
|
+
function decodeDynamic(EncodedLengths _encodedLengths, bytes memory _blob) internal pure returns (${renderArguments2(
|
471
|
+
dynamicFields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`)
|
472
|
+
)}) {
|
473
|
+
${renderList(
|
474
|
+
dynamicFields,
|
475
|
+
// unchecked is only dangerous if _encodedLengths (and _blob) is invalid,
|
476
|
+
// but it's assumed to be valid, and this function is meant to be mostly used internally
|
477
|
+
(field, index) => {
|
478
|
+
if (index === 0) {
|
479
|
+
return `
|
178
480
|
uint256 _start;
|
179
481
|
uint256 _end;
|
180
482
|
unchecked {
|
181
|
-
_end = _encodedLengths.atIndex(${
|
483
|
+
_end = _encodedLengths.atIndex(${index});
|
182
484
|
}
|
183
|
-
${
|
184
|
-
|
485
|
+
${field.name} = ${renderDecodeDynamicFieldPartial(field)};
|
486
|
+
`;
|
487
|
+
} else {
|
488
|
+
return `
|
185
489
|
_start = _end;
|
186
490
|
unchecked {
|
187
|
-
_end += _encodedLengths.atIndex(${
|
491
|
+
_end += _encodedLengths.atIndex(${index});
|
188
492
|
}
|
189
|
-
${
|
190
|
-
|
493
|
+
${field.name} = ${renderDecodeDynamicFieldPartial(field)};
|
494
|
+
`;
|
495
|
+
}
|
496
|
+
}
|
497
|
+
)}
|
191
498
|
}
|
192
|
-
|
499
|
+
`;
|
500
|
+
}
|
501
|
+
result += `
|
193
502
|
/**
|
194
503
|
* @notice Decode the tightly packed blobs using this table's field layout.
|
195
|
-
* ${
|
196
|
-
* ${
|
197
|
-
* ${
|
504
|
+
* ${staticFields.length > 0 ? "@param _staticData Tightly packed static fields." : ""}
|
505
|
+
* ${dynamicFields.length > 0 ? "@param _encodedLengths Encoded lengths of dynamic fields." : ""}
|
506
|
+
* ${dynamicFields.length > 0 ? "@param _dynamicData Tightly packed dynamic fields." : ""}
|
198
507
|
*/
|
199
508
|
function decode(
|
200
|
-
bytes memory ${
|
201
|
-
EncodedLengths ${
|
202
|
-
bytes memory ${
|
203
|
-
) internal pure returns (${
|
204
|
-
|
205
|
-
|
206
|
-
`
|
207
|
-
(${
|
208
|
-
|
509
|
+
bytes memory ${staticFields.length > 0 ? "_staticData" : ""},
|
510
|
+
EncodedLengths ${dynamicFields.length > 0 ? "_encodedLengths" : ""},
|
511
|
+
bytes memory ${dynamicFields.length > 0 ? "_dynamicData" : ""}
|
512
|
+
) internal pure returns (${renderedDecodedRecord}) {
|
513
|
+
`;
|
514
|
+
if (staticFields.length > 0) {
|
515
|
+
result += `
|
516
|
+
(${renderArguments2(staticFields.map((field) => `${fieldNamePrefix}${field.name}`))}) = decodeStatic(_staticData);
|
517
|
+
`;
|
518
|
+
}
|
519
|
+
if (dynamicFields.length > 0) {
|
520
|
+
result += `
|
521
|
+
(${renderArguments2(
|
522
|
+
dynamicFields.map((field) => `${fieldNamePrefix}${field.name}`)
|
523
|
+
)}) = decodeDynamic(_encodedLengths, _dynamicData);
|
524
|
+
`;
|
525
|
+
}
|
526
|
+
result += `
|
209
527
|
}
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
528
|
+
`;
|
529
|
+
return result;
|
530
|
+
}
|
531
|
+
function renderDecodedRecord({ structName, fields }) {
|
532
|
+
if (structName) {
|
533
|
+
return `${structName} memory _table`;
|
534
|
+
} else {
|
535
|
+
return renderArguments2(fields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`));
|
536
|
+
}
|
537
|
+
}
|
538
|
+
function renderDecodeDynamicFieldPartial(field) {
|
539
|
+
const { typeId, arrayElement, typeWrap } = field;
|
540
|
+
if (arrayElement) {
|
541
|
+
return `${typeWrap}(
|
542
|
+
SliceLib.getSubslice(_blob, _start, _end).decodeArray_${arrayElement.typeId}()
|
543
|
+
)`;
|
544
|
+
} else {
|
545
|
+
return `${typeWrap}(
|
546
|
+
${typeId}(
|
214
547
|
SliceLib.getSubslice(_blob, _start, _end).toBytes()
|
215
548
|
)
|
216
|
-
)
|
217
|
-
|
549
|
+
)`;
|
550
|
+
}
|
551
|
+
}
|
552
|
+
|
553
|
+
// ts/codegen/renderTable.ts
|
554
|
+
import {
|
555
|
+
renderArguments as renderArguments3,
|
556
|
+
renderCommonData as renderCommonData3,
|
557
|
+
renderList as renderList2,
|
558
|
+
renderImports,
|
559
|
+
renderTableId,
|
560
|
+
renderTypeHelpers,
|
561
|
+
renderWithStore as renderWithStore3,
|
562
|
+
renderedSolidityHeader,
|
563
|
+
renderImportPath
|
564
|
+
} from "@latticexyz/common/codegen";
|
565
|
+
|
566
|
+
// ts/constants.ts
|
567
|
+
var WORD_SIZE = 32;
|
568
|
+
var WORD_LAST_INDEX = 31;
|
569
|
+
var BYTE_TO_BITS = 8;
|
570
|
+
var MAX_TOTAL_FIELDS = 28;
|
571
|
+
var MAX_DYNAMIC_FIELDS = 5;
|
572
|
+
var LayoutOffsets = {
|
573
|
+
TOTAL_LENGTH: (WORD_SIZE - 2) * BYTE_TO_BITS,
|
574
|
+
NUM_STATIC_FIELDS: (WORD_SIZE - 2 - 1) * BYTE_TO_BITS,
|
575
|
+
NUM_DYNAMIC_FIELDS: (WORD_SIZE - 2 - 1 - 1) * BYTE_TO_BITS
|
576
|
+
};
|
577
|
+
|
578
|
+
// ts/codegen/renderFieldLayout.ts
|
579
|
+
function renderFieldLayout(fields) {
|
580
|
+
return `FieldLayout constant _fieldLayout = FieldLayout.wrap(${encodeFieldLayout(fields)});`;
|
581
|
+
}
|
582
|
+
function encodeFieldLayout(fields) {
|
583
|
+
const staticFields = fields.filter(({ isDynamic }) => !isDynamic);
|
584
|
+
const numDynamicFields = fields.length - staticFields.length;
|
585
|
+
let fieldLayout = 0n;
|
586
|
+
let totalLength = 0;
|
587
|
+
const totalFields = fields.length;
|
588
|
+
if (totalFields > MAX_TOTAL_FIELDS) throw new Error("FieldLayout: too many fields");
|
589
|
+
if (numDynamicFields > MAX_DYNAMIC_FIELDS) throw new Error("FieldLayout: too many dynamic fields");
|
590
|
+
for (let i = 0; i < staticFields.length; i++) {
|
591
|
+
const { isDynamic, staticByteLength } = fields[i];
|
592
|
+
if (isDynamic) throw new Error(`FieldLayout: static type after dynamic type`);
|
593
|
+
totalLength += staticByteLength;
|
594
|
+
fieldLayout |= BigInt(staticByteLength) << BigInt((WORD_LAST_INDEX - 4 - i) * BYTE_TO_BITS);
|
595
|
+
}
|
596
|
+
fieldLayout |= BigInt(totalLength) << BigInt(LayoutOffsets.TOTAL_LENGTH);
|
597
|
+
fieldLayout |= BigInt(staticFields.length) << BigInt(LayoutOffsets.NUM_STATIC_FIELDS);
|
598
|
+
fieldLayout |= BigInt(numDynamicFields) << BigInt(LayoutOffsets.NUM_DYNAMIC_FIELDS);
|
599
|
+
return `0x${fieldLayout.toString(16).padStart(64, "0")}`;
|
600
|
+
}
|
601
|
+
|
602
|
+
// ts/codegen/renderTable.ts
|
603
|
+
import { keySchemaToHex, valueSchemaToHex } from "@latticexyz/protocol-parser/internal";
|
604
|
+
function renderTable(options) {
|
605
|
+
const {
|
606
|
+
imports,
|
607
|
+
libraryName,
|
608
|
+
structName,
|
609
|
+
staticResourceData,
|
610
|
+
storeImportPath,
|
611
|
+
fields,
|
612
|
+
staticFields,
|
613
|
+
dynamicFields,
|
614
|
+
withRecordMethods,
|
615
|
+
storeArgument,
|
616
|
+
keyTuple
|
617
|
+
} = options;
|
618
|
+
const { _typedTableId, _typedKeyArgs, _keyTupleDefinition } = renderCommonData3(options);
|
619
|
+
return `
|
620
|
+
${renderedSolidityHeader}
|
218
621
|
|
219
622
|
// Import store internals
|
220
|
-
import { IStore } from "${
|
221
|
-
import { StoreSwitch } from "${
|
222
|
-
import { StoreCore } from "${
|
223
|
-
import { Bytes } from "${
|
224
|
-
import { Memory } from "${
|
225
|
-
import { SliceLib } from "${
|
226
|
-
import { EncodeArray } from "${
|
227
|
-
import { FieldLayout } from "${
|
228
|
-
import { Schema } from "${
|
229
|
-
import { EncodedLengths, EncodedLengthsLib } from "${
|
230
|
-
import { ResourceId } from "${
|
231
|
-
|
232
|
-
${
|
623
|
+
import { IStore } from "${renderImportPath(storeImportPath, "IStore.sol")}";
|
624
|
+
import { StoreSwitch } from "${renderImportPath(storeImportPath, "StoreSwitch.sol")}";
|
625
|
+
import { StoreCore } from "${renderImportPath(storeImportPath, "StoreCore.sol")}";
|
626
|
+
import { Bytes } from "${renderImportPath(storeImportPath, "Bytes.sol")}";
|
627
|
+
import { Memory } from "${renderImportPath(storeImportPath, "Memory.sol")}";
|
628
|
+
import { SliceLib } from "${renderImportPath(storeImportPath, "Slice.sol")}";
|
629
|
+
import { EncodeArray } from "${renderImportPath(storeImportPath, "tightcoder/EncodeArray.sol")}";
|
630
|
+
import { FieldLayout } from "${renderImportPath(storeImportPath, "FieldLayout.sol")}";
|
631
|
+
import { Schema } from "${renderImportPath(storeImportPath, "Schema.sol")}";
|
632
|
+
import { EncodedLengths, EncodedLengthsLib } from "${renderImportPath(storeImportPath, "EncodedLengths.sol")}";
|
633
|
+
import { ResourceId } from "${renderImportPath(storeImportPath, "ResourceId.sol")}";
|
634
|
+
|
635
|
+
${imports.length > 0 ? `
|
233
636
|
// Import user types
|
234
|
-
${
|
235
|
-
|
637
|
+
${renderImports(imports)}
|
638
|
+
` : ""}
|
236
639
|
|
237
|
-
${
|
238
|
-
struct ${
|
239
|
-
${
|
640
|
+
${!structName ? "" : `
|
641
|
+
struct ${structName} {
|
642
|
+
${renderList2(fields, ({ name, typeId }) => `${typeId} ${name};`)}
|
240
643
|
}
|
241
|
-
|
644
|
+
`}
|
242
645
|
|
243
|
-
library ${
|
244
|
-
${
|
646
|
+
library ${libraryName} {
|
647
|
+
${staticResourceData ? renderTableId(staticResourceData) : ""}
|
245
648
|
|
246
|
-
${
|
649
|
+
${renderFieldLayout(fields)}
|
247
650
|
|
248
|
-
// Hex-encoded key schema of (${
|
249
|
-
Schema constant _keySchema = Schema.wrap(${
|
250
|
-
|
251
|
-
|
651
|
+
// Hex-encoded key schema of (${keyTuple.map((field) => field.internalTypeId).join(", ")})
|
652
|
+
Schema constant _keySchema = Schema.wrap(${keySchemaToHex(
|
653
|
+
Object.fromEntries(keyTuple.map((field) => [field.name, field.internalTypeId]))
|
654
|
+
)});
|
655
|
+
// Hex-encoded value schema of (${fields.map((field) => field.internalTypeId).join(", ")})
|
656
|
+
Schema constant _valueSchema = Schema.wrap(${valueSchemaToHex(
|
657
|
+
Object.fromEntries(fields.map((field) => [field.name, field.internalTypeId]))
|
658
|
+
)});
|
252
659
|
|
253
660
|
/**
|
254
661
|
* @notice Get the table's key field names.
|
255
662
|
* @return keyNames An array of strings with the names of key fields.
|
256
663
|
*/
|
257
664
|
function getKeyNames() internal pure returns (string[] memory keyNames) {
|
258
|
-
keyNames = new string[](${
|
259
|
-
${
|
665
|
+
keyNames = new string[](${keyTuple.length});
|
666
|
+
${renderList2(keyTuple, (keyElement, index) => `keyNames[${index}] = "${keyElement.name}";`)}
|
260
667
|
}
|
261
668
|
|
262
669
|
/**
|
@@ -264,30 +671,33 @@ import{renderArguments as S,renderCommonData as se,renderWithFieldSuffix as _,re
|
|
264
671
|
* @return fieldNames An array of strings with the names of value fields.
|
265
672
|
*/
|
266
673
|
function getFieldNames() internal pure returns (string[] memory fieldNames) {
|
267
|
-
fieldNames = new string[](${
|
268
|
-
${
|
674
|
+
fieldNames = new string[](${fields.length});
|
675
|
+
${renderList2(fields, (field, index) => `fieldNames[${index}] = "${field.name}";`)}
|
269
676
|
}
|
270
677
|
|
271
|
-
${
|
678
|
+
${renderWithStore3(
|
679
|
+
storeArgument,
|
680
|
+
({ _typedStore, _store, _commentSuffix, _methodNamePrefix }) => `
|
272
681
|
/**
|
273
|
-
* @notice Register the table with its config${
|
682
|
+
* @notice Register the table with its config${_commentSuffix}.
|
274
683
|
*/
|
275
|
-
function ${
|
276
|
-
${
|
684
|
+
function ${_methodNamePrefix}register(${renderArguments3([_typedStore, _typedTableId])}) internal {
|
685
|
+
${_store}.registerTable(_tableId, _fieldLayout, _keySchema, _valueSchema, getKeyNames(), getFieldNames());
|
277
686
|
}
|
278
|
-
`
|
687
|
+
`
|
688
|
+
)}
|
279
689
|
|
280
|
-
${
|
690
|
+
${renderFieldMethods(options)}
|
281
691
|
|
282
|
-
${
|
692
|
+
${withRecordMethods ? renderRecordMethods(options) : ""}
|
283
693
|
|
284
|
-
${
|
694
|
+
${renderDeleteRecordMethods(options)}
|
285
695
|
|
286
|
-
${
|
696
|
+
${renderEncodeStatic(staticFields)}
|
287
697
|
|
288
|
-
${
|
698
|
+
${renderEncodeLengths(dynamicFields)}
|
289
699
|
|
290
|
-
${
|
700
|
+
${renderEncodeDynamic(dynamicFields)}
|
291
701
|
|
292
702
|
/**
|
293
703
|
* @notice Encode all of a record's fields.
|
@@ -295,8 +705,10 @@ import{renderArguments as S,renderCommonData as se,renderWithFieldSuffix as _,re
|
|
295
705
|
* @return The lengths of the dynamic fields (packed into a single bytes32 value).
|
296
706
|
* @return The dynamic (variable length) data, encoded into a sequence of bytes.
|
297
707
|
*/
|
298
|
-
function encode(${
|
299
|
-
|
708
|
+
function encode(${renderArguments3(
|
709
|
+
options.fields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`)
|
710
|
+
)}) internal pure returns (bytes memory, EncodedLengths, bytes memory) {
|
711
|
+
${renderRecordData(options)}
|
300
712
|
|
301
713
|
return (_staticData, _encodedLengths, _dynamicData);
|
302
714
|
}
|
@@ -304,87 +716,423 @@ import{renderArguments as S,renderCommonData as se,renderWithFieldSuffix as _,re
|
|
304
716
|
/**
|
305
717
|
* @notice Encode keys as a bytes32 array using this table's field layout.
|
306
718
|
*/
|
307
|
-
function encodeKeyTuple(${
|
308
|
-
${
|
719
|
+
function encodeKeyTuple(${renderArguments3([_typedKeyArgs])}) internal pure returns (bytes32[] memory) {
|
720
|
+
${_keyTupleDefinition}
|
309
721
|
return _keyTuple;
|
310
722
|
}
|
311
723
|
}
|
312
724
|
|
313
|
-
${
|
314
|
-
|
725
|
+
${renderTypeHelpers(options)}
|
726
|
+
`;
|
727
|
+
}
|
728
|
+
function renderEncodeStatic(staticFields) {
|
729
|
+
if (staticFields.length === 0) return "";
|
730
|
+
return `
|
315
731
|
/**
|
316
732
|
* @notice Tightly pack static (fixed length) data using this table's schema.
|
317
733
|
* @return The static data, encoded into a sequence of bytes.
|
318
734
|
*/
|
319
|
-
function encodeStatic(${
|
320
|
-
|
735
|
+
function encodeStatic(${renderArguments3(
|
736
|
+
staticFields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`)
|
737
|
+
)}) internal pure returns (bytes memory) {
|
738
|
+
return abi.encodePacked(${renderArguments3(staticFields.map(({ name }) => name))});
|
321
739
|
}
|
322
|
-
|
740
|
+
`;
|
741
|
+
}
|
742
|
+
function renderEncodeLengths(dynamicFields) {
|
743
|
+
if (dynamicFields.length === 0) return "";
|
744
|
+
return `
|
323
745
|
/**
|
324
746
|
* @notice Tightly pack dynamic data lengths using this table's schema.
|
325
747
|
* @return _encodedLengths The lengths of the dynamic fields (packed into a single bytes32 value).
|
326
748
|
*/
|
327
|
-
function encodeLengths(${
|
749
|
+
function encodeLengths(${renderArguments3(
|
750
|
+
dynamicFields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`)
|
751
|
+
)}) internal pure returns (EncodedLengths _encodedLengths) {
|
328
752
|
// Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits
|
329
753
|
unchecked {
|
330
754
|
_encodedLengths = EncodedLengthsLib.pack(
|
331
|
-
${
|
755
|
+
${renderArguments3(
|
756
|
+
dynamicFields.map(({ name, arrayElement }) => {
|
757
|
+
if (arrayElement) {
|
758
|
+
return `${name}.length * ${arrayElement.staticByteLength}`;
|
759
|
+
} else {
|
760
|
+
return `bytes(${name}).length`;
|
761
|
+
}
|
762
|
+
})
|
763
|
+
)}
|
332
764
|
);
|
333
765
|
}
|
334
766
|
}
|
335
|
-
|
767
|
+
`;
|
768
|
+
}
|
769
|
+
function renderEncodeDynamic(dynamicFields) {
|
770
|
+
if (dynamicFields.length === 0) return "";
|
771
|
+
return `
|
336
772
|
/**
|
337
773
|
* @notice Tightly pack dynamic (variable length) data using this table's schema.
|
338
774
|
* @return The dynamic data, encoded into a sequence of bytes.
|
339
775
|
*/
|
340
|
-
function encodeDynamic(${
|
341
|
-
|
776
|
+
function encodeDynamic(${renderArguments3(
|
777
|
+
dynamicFields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`)
|
778
|
+
)}) internal pure returns (bytes memory) {
|
779
|
+
return abi.encodePacked(${renderArguments3(dynamicFields.map((field) => renderEncodeFieldSingle(field)))});
|
780
|
+
}
|
781
|
+
`;
|
782
|
+
}
|
783
|
+
|
784
|
+
// ts/codegen/renderTypesFromConfig.ts
|
785
|
+
import { renderEnums } from "@latticexyz/common/codegen";
|
786
|
+
function renderTypesFromConfig(config) {
|
787
|
+
return renderEnums(config.enums);
|
788
|
+
}
|
789
|
+
|
790
|
+
// ts/codegen/tablegen.ts
|
791
|
+
import fs from "node:fs/promises";
|
792
|
+
import path4 from "node:path";
|
793
|
+
import { formatAndWriteSolidity, renderEnums as renderEnums2 } from "@latticexyz/common/codegen";
|
794
|
+
|
795
|
+
// ts/codegen/renderTableIndex.ts
|
796
|
+
import { renderImportPath as renderImportPath2, renderList as renderList3, renderedSolidityHeader as renderedSolidityHeader2 } from "@latticexyz/common/codegen";
|
797
|
+
import path from "node:path";
|
798
|
+
function renderTableIndex(codegenIndexPath, options) {
|
799
|
+
return `
|
800
|
+
${renderedSolidityHeader2}
|
801
|
+
|
802
|
+
${renderList3(options, ({ outputPath, tableName, renderOptions: { structName } }) => {
|
803
|
+
const imports = [tableName];
|
804
|
+
if (structName) imports.push(structName);
|
805
|
+
return `import { ${imports.join(", ")} } from "${renderImportPath2("./" + path.relative(path.dirname(codegenIndexPath), outputPath))}";`;
|
806
|
+
})}
|
807
|
+
`;
|
808
|
+
}
|
809
|
+
|
810
|
+
// ts/codegen/tablegen.ts
|
811
|
+
import { uniqueBy } from "@latticexyz/common/utils";
|
812
|
+
|
813
|
+
// ts/codegen/getUserTypesFilename.ts
|
814
|
+
import path2 from "node:path";
|
815
|
+
function getUserTypesFilename({ config }) {
|
816
|
+
return path2.join(config.sourceDirectory, config.codegen.outputDirectory, config.codegen.userTypesFilename);
|
817
|
+
}
|
818
|
+
|
819
|
+
// ts/codegen/getUserTypes.ts
|
820
|
+
import { groupBy } from "@latticexyz/common/utils";
|
821
|
+
function getUserTypes({ config }) {
|
822
|
+
const enums = Object.keys(config.enums).map(
|
823
|
+
(name) => ({
|
824
|
+
type: "enum",
|
825
|
+
name,
|
826
|
+
abiType: "uint8",
|
827
|
+
importPath: "./" + getUserTypesFilename({ config })
|
828
|
+
})
|
829
|
+
);
|
830
|
+
const userTypes = Object.entries(config.userTypes).map(
|
831
|
+
([name, userType]) => ({
|
832
|
+
type: "userType",
|
833
|
+
name,
|
834
|
+
abiType: userType.type,
|
835
|
+
// If `userType.filePath` starts with a `.`, it's relative to the root dir
|
836
|
+
importPath: userType.filePath
|
837
|
+
})
|
838
|
+
);
|
839
|
+
const result = [...enums, ...userTypes];
|
840
|
+
const duplicates = Array.from(groupBy(result, (userType) => userType.name).entries()).filter(([, entries]) => entries.length > 1).map(([name]) => name);
|
841
|
+
if (duplicates.length > 0) {
|
842
|
+
throw new Error(`Found enums and user types sharing the same name: ${duplicates.join(", ")}`);
|
843
|
+
}
|
844
|
+
return result;
|
845
|
+
}
|
846
|
+
|
847
|
+
// ts/codegen/getTableOptions.ts
|
848
|
+
import path3 from "path";
|
849
|
+
import { SchemaTypeArrayToElement } from "@latticexyz/schema-type/deprecated";
|
850
|
+
|
851
|
+
// ts/codegen/userType.ts
|
852
|
+
import {
|
853
|
+
AbiTypeToSchemaType,
|
854
|
+
getStaticByteLength,
|
855
|
+
SchemaType,
|
856
|
+
SchemaTypeToAbiType
|
857
|
+
} from "@latticexyz/schema-type/deprecated";
|
858
|
+
function parseStaticArray(abiType) {
|
859
|
+
const matches = abiType.match(/^(\w+)\[(\d+)\]$/);
|
860
|
+
if (!matches) return null;
|
861
|
+
return {
|
862
|
+
elementType: matches[1],
|
863
|
+
staticLength: Number.parseInt(matches[2])
|
864
|
+
};
|
865
|
+
}
|
866
|
+
function resolveAbiOrUserType(abiOrUserType, userTypes) {
|
867
|
+
if (abiOrUserType in AbiTypeToSchemaType) {
|
868
|
+
const schemaType = AbiTypeToSchemaType[abiOrUserType];
|
869
|
+
return {
|
870
|
+
schemaType,
|
871
|
+
renderType: getSchemaTypeInfo(schemaType)
|
872
|
+
};
|
873
|
+
}
|
874
|
+
const staticArray = parseStaticArray(abiOrUserType);
|
875
|
+
if (staticArray) {
|
876
|
+
if (staticArray.elementType in AbiTypeToSchemaType) {
|
877
|
+
return getStaticArrayTypeInfo(abiOrUserType, staticArray.elementType, staticArray.staticLength);
|
878
|
+
} else {
|
879
|
+
throw new Error("Static arrays of user types are not supported");
|
880
|
+
}
|
881
|
+
}
|
882
|
+
const userType = userTypes.find((type) => type.name === abiOrUserType);
|
883
|
+
if (!userType) {
|
884
|
+
throw new Error(`User type "${abiOrUserType}" not found`);
|
885
|
+
}
|
886
|
+
return getUserTypeInfo(userType);
|
887
|
+
}
|
888
|
+
function getSchemaTypeInfo(schemaType) {
|
889
|
+
const staticByteLength = getStaticByteLength(schemaType);
|
890
|
+
const isDynamic = staticByteLength === 0;
|
891
|
+
const typeId = SchemaTypeToAbiType[schemaType];
|
892
|
+
return {
|
893
|
+
typeId,
|
894
|
+
typeWithLocation: isDynamic ? typeId + " memory" : typeId,
|
895
|
+
enumName: SchemaType[schemaType],
|
896
|
+
staticByteLength,
|
897
|
+
isDynamic,
|
898
|
+
typeWrap: "",
|
899
|
+
typeUnwrap: "",
|
900
|
+
internalTypeId: typeId
|
901
|
+
};
|
902
|
+
}
|
903
|
+
function getUserTypeInfo(userType) {
|
904
|
+
switch (userType.type) {
|
905
|
+
case "enum": {
|
906
|
+
const schemaType = SchemaType.UINT8;
|
907
|
+
const staticByteLength = getStaticByteLength(schemaType);
|
908
|
+
const isDynamic = staticByteLength === 0;
|
909
|
+
return {
|
910
|
+
schemaType,
|
911
|
+
renderType: {
|
912
|
+
typeId: userType.name,
|
913
|
+
typeWithLocation: userType.name,
|
914
|
+
enumName: SchemaType[schemaType],
|
915
|
+
staticByteLength,
|
916
|
+
isDynamic,
|
917
|
+
typeWrap: userType.name,
|
918
|
+
typeUnwrap: userType.abiType,
|
919
|
+
internalTypeId: userType.abiType
|
920
|
+
}
|
921
|
+
};
|
922
|
+
}
|
923
|
+
case "userType": {
|
924
|
+
const schemaType = AbiTypeToSchemaType[userType.abiType];
|
925
|
+
return {
|
926
|
+
schemaType,
|
927
|
+
renderType: {
|
928
|
+
typeId: userType.name,
|
929
|
+
typeWithLocation: userType.name,
|
930
|
+
enumName: SchemaType[schemaType],
|
931
|
+
staticByteLength: getStaticByteLength(schemaType),
|
932
|
+
isDynamic: false,
|
933
|
+
typeWrap: `${userType.name}.wrap`,
|
934
|
+
typeUnwrap: `${userType.name}.unwrap`,
|
935
|
+
internalTypeId: userType.abiType
|
936
|
+
}
|
937
|
+
};
|
938
|
+
}
|
939
|
+
}
|
940
|
+
}
|
941
|
+
function getStaticArrayTypeInfo(abiType, elementType, staticLength) {
|
942
|
+
const internalTypeId = elementType + "[]";
|
943
|
+
const schemaType = AbiTypeToSchemaType[internalTypeId];
|
944
|
+
return {
|
945
|
+
schemaType,
|
946
|
+
renderType: {
|
947
|
+
typeId: abiType,
|
948
|
+
typeWithLocation: `${abiType} memory`,
|
949
|
+
enumName: SchemaType[schemaType],
|
950
|
+
staticByteLength: 0,
|
951
|
+
isDynamic: true,
|
952
|
+
typeWrap: `toStaticArray_${elementType}_${staticLength}`,
|
953
|
+
typeUnwrap: `fromStaticArray_${elementType}_${staticLength}`,
|
954
|
+
typeWrappingData: {
|
955
|
+
kind: "staticArray",
|
956
|
+
elementType,
|
957
|
+
staticLength
|
958
|
+
},
|
959
|
+
internalTypeId
|
342
960
|
}
|
343
|
-
|
344
|
-
|
961
|
+
};
|
962
|
+
}
|
963
|
+
|
964
|
+
// ts/codegen/getTableOptions.ts
|
965
|
+
import { getKeySchema, getValueSchema } from "@latticexyz/protocol-parser/internal";
|
966
|
+
import { isDefined } from "@latticexyz/common/utils";
|
967
|
+
function getTableOptions({
|
968
|
+
tables,
|
969
|
+
rootDir,
|
970
|
+
codegenDir,
|
971
|
+
userTypes,
|
972
|
+
storeImportPath
|
973
|
+
}) {
|
974
|
+
const options = tables.map((table) => {
|
975
|
+
const outputPath = path3.join(rootDir, codegenDir, table.codegen.outputDirectory, `${table.label}.sol`);
|
976
|
+
const keySchema = getKeySchema(table);
|
977
|
+
const valueSchema = getValueSchema(table);
|
978
|
+
const withStruct = table.codegen.dataStruct;
|
979
|
+
const withRecordMethods = withStruct || table.type === "offchainTable" || Object.keys(valueSchema).length > 1;
|
980
|
+
const withSuffixlessFieldMethods = !withRecordMethods && Object.keys(valueSchema).length === 1;
|
981
|
+
const imports = Object.values(table.schema).map((field) => userTypes.find((type) => type.name === field.internalType)).filter(isDefined).map((userType) => {
|
982
|
+
return {
|
983
|
+
// If it's a fully qualified name, remove trailing references
|
984
|
+
// This enables support for user types inside libraries
|
985
|
+
symbol: userType.name.replace(/\..*$/, ""),
|
986
|
+
path: userType.importPath.startsWith(".") ? "./" + path3.relative(path3.dirname(outputPath), path3.join(rootDir, userType.importPath)) : userType.importPath
|
987
|
+
};
|
988
|
+
});
|
989
|
+
const keyTuple = Object.entries(keySchema).map(([name, field]) => {
|
990
|
+
const { renderType } = resolveAbiOrUserType(field.internalType, userTypes);
|
991
|
+
return {
|
992
|
+
...renderType,
|
993
|
+
name,
|
994
|
+
isDynamic: false
|
995
|
+
};
|
996
|
+
});
|
997
|
+
const fields = Object.entries(valueSchema).map(([name, field]) => {
|
998
|
+
const { renderType, schemaType } = resolveAbiOrUserType(field.internalType, userTypes);
|
999
|
+
const elementType = SchemaTypeArrayToElement[schemaType];
|
1000
|
+
return {
|
1001
|
+
...renderType,
|
1002
|
+
arrayElement: elementType !== void 0 ? getSchemaTypeInfo(elementType) : void 0,
|
1003
|
+
name
|
1004
|
+
};
|
1005
|
+
});
|
1006
|
+
const staticFields = fields.filter(({ isDynamic }) => !isDynamic);
|
1007
|
+
const dynamicFields = fields.filter(({ isDynamic }) => isDynamic);
|
1008
|
+
const staticResourceData = table.codegen.tableIdArgument ? void 0 : {
|
1009
|
+
namespace: table.namespace,
|
1010
|
+
name: table.name,
|
1011
|
+
offchainOnly: table.type === "offchainTable"
|
1012
|
+
};
|
1013
|
+
return {
|
1014
|
+
outputPath,
|
1015
|
+
tableName: table.label,
|
1016
|
+
renderOptions: {
|
1017
|
+
imports,
|
1018
|
+
libraryName: table.label,
|
1019
|
+
structName: withStruct ? table.label + "Data" : void 0,
|
1020
|
+
staticResourceData,
|
1021
|
+
storeImportPath: storeImportPath.startsWith(".") ? "./" + path3.relative(path3.dirname(outputPath), path3.join(rootDir, storeImportPath)) : storeImportPath,
|
1022
|
+
keyTuple,
|
1023
|
+
fields,
|
1024
|
+
staticFields,
|
1025
|
+
dynamicFields,
|
1026
|
+
withGetters: table.type === "table",
|
1027
|
+
withRecordMethods,
|
1028
|
+
withDynamicFieldMethods: table.type === "table",
|
1029
|
+
withSuffixlessFieldMethods,
|
1030
|
+
storeArgument: table.codegen.storeArgument
|
1031
|
+
}
|
1032
|
+
};
|
1033
|
+
});
|
1034
|
+
return options;
|
1035
|
+
}
|
1036
|
+
|
1037
|
+
// ts/codegen/tablegen.ts
|
1038
|
+
import debug from "debug";
|
1039
|
+
async function tablegen({ rootDir, config }) {
|
1040
|
+
const userTypes = getUserTypes({ config });
|
1041
|
+
if (Object.keys(config.enums).length > 0) {
|
1042
|
+
const userTypesFilename = path4.join(rootDir, getUserTypesFilename({ config }));
|
1043
|
+
const source = renderEnums2(config.enums);
|
1044
|
+
await formatAndWriteSolidity(source, userTypesFilename, "Generated types file with enums");
|
1045
|
+
}
|
1046
|
+
await Promise.all(
|
1047
|
+
Object.values(config.namespaces).map(async (namespace) => {
|
1048
|
+
const sourceDir = config.multipleNamespaces ? path4.join(config.sourceDirectory, "namespaces", namespace.label) : config.sourceDirectory;
|
1049
|
+
const codegenDir = path4.join(sourceDir, config.codegen.outputDirectory);
|
1050
|
+
const tables = Object.values(namespace.tables);
|
1051
|
+
if (tables.length === 0) return;
|
1052
|
+
const tableOptions = getTableOptions({
|
1053
|
+
tables,
|
1054
|
+
rootDir,
|
1055
|
+
codegenDir,
|
1056
|
+
userTypes,
|
1057
|
+
storeImportPath: config.codegen.storeImportPath
|
1058
|
+
});
|
1059
|
+
const tableDirs = uniqueBy(
|
1060
|
+
tableOptions.map(({ outputPath }) => path4.dirname(outputPath)),
|
1061
|
+
(dir) => dir
|
1062
|
+
);
|
1063
|
+
await Promise.all(tableDirs.map((dir) => fs.rm(dir, { recursive: true, force: true })));
|
1064
|
+
await Promise.all(
|
1065
|
+
tableOptions.map(async ({ outputPath, renderOptions }) => {
|
1066
|
+
const source = renderTable(renderOptions);
|
1067
|
+
return await formatAndWriteSolidity(source, outputPath, "Generated table");
|
1068
|
+
})
|
1069
|
+
);
|
1070
|
+
if (config.codegen.indexFilename !== false && tableOptions.length > 0) {
|
1071
|
+
const codegenIndexPath = path4.join(rootDir, codegenDir, config.codegen.indexFilename);
|
1072
|
+
const source = renderTableIndex(codegenIndexPath, tableOptions);
|
1073
|
+
await formatAndWriteSolidity(source, codegenIndexPath, "Generated table index");
|
1074
|
+
}
|
1075
|
+
})
|
1076
|
+
);
|
1077
|
+
debug("Generated tables");
|
1078
|
+
}
|
1079
|
+
|
1080
|
+
// ts/codegen/tightcoder/renderDecodeSlice.ts
|
1081
|
+
import { renderedSolidityHeader as renderedSolidityHeader3 } from "@latticexyz/common/codegen";
|
1082
|
+
import { staticAbiTypeToByteLength, staticAbiTypes } from "@latticexyz/schema-type/internal";
|
345
1083
|
|
346
|
-
|
347
|
-
|
1084
|
+
// ts/codegen/tightcoder/renderFunctions.ts
|
1085
|
+
import { getLeftPaddingBits } from "@latticexyz/common/codegen";
|
1086
|
+
function renderTightCoderDecode(element) {
|
1087
|
+
return `
|
348
1088
|
/**
|
349
|
-
* @notice Decodes a slice into an array of ${
|
1089
|
+
* @notice Decodes a slice into an array of ${element.internalTypeId}.
|
350
1090
|
* @dev Uses TightCoder for initial decoding, and then assembly for memory conversion.
|
351
1091
|
* @param _input The slice to decode.
|
352
|
-
* @return _output The decoded array of ${
|
1092
|
+
* @return _output The decoded array of ${element.internalTypeId}.
|
353
1093
|
*/
|
354
|
-
function decodeArray_${
|
1094
|
+
function decodeArray_${element.internalTypeId}(
|
355
1095
|
Slice _input
|
356
1096
|
) internal pure returns (
|
357
|
-
${
|
1097
|
+
${element.internalTypeId}[] memory _output
|
358
1098
|
) {
|
359
1099
|
bytes32[] memory _genericArray = TightCoder.decode(
|
360
1100
|
_input,
|
361
|
-
${
|
362
|
-
${
|
1101
|
+
${element.staticByteLength},
|
1102
|
+
${getLeftPaddingBits(element)}
|
363
1103
|
);
|
364
1104
|
assembly {
|
365
1105
|
_output := _genericArray
|
366
1106
|
}
|
367
1107
|
}
|
368
|
-
|
1108
|
+
`;
|
1109
|
+
}
|
1110
|
+
function renderTightCoderEncode(element) {
|
1111
|
+
return `
|
369
1112
|
|
370
1113
|
/**
|
371
|
-
* @notice Encodes an array of ${
|
372
|
-
* @param _input The array of ${
|
1114
|
+
* @notice Encodes an array of ${element.internalTypeId} into a tightly packed bytes representation.
|
1115
|
+
* @param _input The array of ${element.internalTypeId} values to be encoded.
|
373
1116
|
* @return The resulting tightly packed bytes representation of the input array.
|
374
1117
|
*/
|
375
|
-
function encode(${
|
1118
|
+
function encode(${element.internalTypeId}[] memory _input) internal pure returns (bytes memory) {
|
376
1119
|
bytes32[] memory _genericArray;
|
377
1120
|
assembly {
|
378
1121
|
_genericArray := _input
|
379
1122
|
}
|
380
1123
|
return TightCoder.encode(
|
381
1124
|
_genericArray,
|
382
|
-
${
|
383
|
-
${
|
1125
|
+
${element.staticByteLength},
|
1126
|
+
${getLeftPaddingBits(element)}
|
384
1127
|
);
|
385
1128
|
}
|
386
|
-
|
387
|
-
|
1129
|
+
`;
|
1130
|
+
}
|
1131
|
+
|
1132
|
+
// ts/codegen/tightcoder/renderDecodeSlice.ts
|
1133
|
+
function renderDecodeSlice() {
|
1134
|
+
return `
|
1135
|
+
${renderedSolidityHeader3}
|
388
1136
|
import { TightCoder } from "./TightCoder.sol";
|
389
1137
|
import { Slice } from "../Slice.sol";
|
390
1138
|
|
@@ -395,11 +1143,22 @@ import{renderArguments as S,renderCommonData as se,renderWithFieldSuffix as _,re
|
|
395
1143
|
* @dev This library provides functions for decoding slices into arrays of basic uint types.
|
396
1144
|
*/
|
397
1145
|
library DecodeSlice {
|
398
|
-
${
|
399
|
-
|
1146
|
+
${staticAbiTypes.map(
|
1147
|
+
(staticAbiType) => renderTightCoderDecode({
|
1148
|
+
internalTypeId: staticAbiType,
|
1149
|
+
staticByteLength: staticAbiTypeToByteLength[staticAbiType]
|
1150
|
+
})
|
1151
|
+
).join("\n")}
|
400
1152
|
}
|
401
|
-
|
402
|
-
|
1153
|
+
`;
|
1154
|
+
}
|
1155
|
+
|
1156
|
+
// ts/codegen/tightcoder/renderEncodeArray.ts
|
1157
|
+
import { renderedSolidityHeader as renderedSolidityHeader4 } from "@latticexyz/common/codegen";
|
1158
|
+
import { staticAbiTypeToByteLength as staticAbiTypeToByteLength2, staticAbiTypes as staticAbiTypes2 } from "@latticexyz/schema-type/internal";
|
1159
|
+
function renderEncodeArray() {
|
1160
|
+
return `
|
1161
|
+
${renderedSolidityHeader4}
|
403
1162
|
import { TightCoder } from "./TightCoder.sol";
|
404
1163
|
|
405
1164
|
/**
|
@@ -408,16 +1167,27 @@ import{renderArguments as S,renderCommonData as se,renderWithFieldSuffix as _,re
|
|
408
1167
|
* @dev This library provides utilities for encoding arrays into tightly packed bytes representations.
|
409
1168
|
*/
|
410
1169
|
library EncodeArray {
|
411
|
-
${
|
412
|
-
|
1170
|
+
${staticAbiTypes2.map(
|
1171
|
+
(staticAbiType) => renderTightCoderEncode({
|
1172
|
+
internalTypeId: staticAbiType,
|
1173
|
+
staticByteLength: staticAbiTypeToByteLength2[staticAbiType]
|
1174
|
+
})
|
1175
|
+
).join("\n")}
|
413
1176
|
}
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
1177
|
+
`;
|
1178
|
+
}
|
1179
|
+
|
1180
|
+
// ts/codegen/tightcoder/renderTightCoderAutoTest.ts
|
1181
|
+
import { renderedSolidityHeader as renderedSolidityHeader5 } from "@latticexyz/common/codegen";
|
1182
|
+
import { staticAbiTypes as staticAbiTypes3 } from "@latticexyz/schema-type/internal";
|
1183
|
+
function renderTightCoderAutoTestFunction({ typeId }) {
|
1184
|
+
return `
|
1185
|
+
function testEncodeDecodeArray_${typeId}(
|
1186
|
+
${typeId} val0,
|
1187
|
+
${typeId} val1,
|
1188
|
+
${typeId} val2
|
419
1189
|
) public {
|
420
|
-
${
|
1190
|
+
${typeId}[] memory input = new ${typeId}[](3);
|
421
1191
|
input[0] = val0;
|
422
1192
|
input[1] = val1;
|
423
1193
|
input[2] = val2;
|
@@ -425,21 +1195,46 @@ import{renderArguments as S,renderCommonData as se,renderWithFieldSuffix as _,re
|
|
425
1195
|
bytes memory encoded = EncodeArray.encode(input);
|
426
1196
|
assertEq(encoded, abi.encodePacked(val0, val1, val2));
|
427
1197
|
|
428
|
-
${
|
1198
|
+
${typeId}[] memory decoded = SliceLib.fromBytes(encoded).decodeArray_${typeId}();
|
429
1199
|
assertEq(decoded.length, 3);
|
430
1200
|
assertEq(decoded[0], val0);
|
431
1201
|
assertEq(decoded[1], val1);
|
432
1202
|
assertEq(decoded[2], val2);
|
433
1203
|
}
|
434
|
-
|
435
|
-
|
1204
|
+
`;
|
1205
|
+
}
|
1206
|
+
function renderTightCoderAutoTest() {
|
1207
|
+
return `
|
1208
|
+
${renderedSolidityHeader5}
|
436
1209
|
|
437
1210
|
import { Test } from "forge-std/Test.sol";
|
438
1211
|
import { EncodeArray } from "../../src/tightcoder/EncodeArray.sol";
|
439
1212
|
import { SliceLib } from "../../src/Slice.sol";
|
440
1213
|
|
441
1214
|
contract TightCoderAutoTest is Test {
|
442
|
-
${
|
1215
|
+
${staticAbiTypes3.map((staticAbiType) => renderTightCoderAutoTestFunction({ typeId: staticAbiType })).join("")}
|
443
1216
|
}
|
444
|
-
|
1217
|
+
`;
|
1218
|
+
}
|
1219
|
+
export {
|
1220
|
+
getSchemaTypeInfo,
|
1221
|
+
getTableOptions,
|
1222
|
+
getUserTypeInfo,
|
1223
|
+
renderDecodeSlice,
|
1224
|
+
renderDecodeValueType,
|
1225
|
+
renderDeleteRecordMethods,
|
1226
|
+
renderEncodeArray,
|
1227
|
+
renderEncodeFieldSingle,
|
1228
|
+
renderFieldMethods,
|
1229
|
+
renderRecordData,
|
1230
|
+
renderRecordMethods,
|
1231
|
+
renderTable,
|
1232
|
+
renderTightCoderAutoTest,
|
1233
|
+
renderTightCoderAutoTestFunction,
|
1234
|
+
renderTightCoderDecode,
|
1235
|
+
renderTightCoderEncode,
|
1236
|
+
renderTypesFromConfig,
|
1237
|
+
resolveAbiOrUserType,
|
1238
|
+
tablegen
|
1239
|
+
};
|
445
1240
|
//# sourceMappingURL=codegen.js.map
|