@colyseus/schema 4.0.26 → 4.0.28
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/README.md +23 -0
- package/build/codegen/cli.cjs +13 -5
- package/build/codegen/cli.cjs.map +1 -1
- package/build/encoder/Encoder.d.ts +2 -0
- package/build/index.cjs +33 -26
- package/build/index.cjs.map +1 -1
- package/build/index.js +33 -26
- package/build/index.mjs +33 -26
- package/build/index.mjs.map +1 -1
- package/package.json +7 -2
- package/src/codegen/cli.ts +4 -4
- package/src/codegen/parser.ts +10 -1
- package/src/encoder/Encoder.ts +32 -29
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colyseus/schema",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.28",
|
|
4
4
|
"description": "Binary state serializer with delta encoding for games",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -82,7 +82,12 @@
|
|
|
82
82
|
"typescript": "^5.9.3"
|
|
83
83
|
},
|
|
84
84
|
"peerDependencies": {
|
|
85
|
-
"typescript": "
|
|
85
|
+
"typescript": ">=5.0.0"
|
|
86
|
+
},
|
|
87
|
+
"peerDependenciesMeta": {
|
|
88
|
+
"typescript": {
|
|
89
|
+
"optional": true
|
|
90
|
+
}
|
|
86
91
|
},
|
|
87
92
|
"c8": {
|
|
88
93
|
"include": [
|
package/src/codegen/cli.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import argv from "./argv.js";
|
|
2
2
|
import { generate, generators } from "./api.js";
|
|
3
3
|
|
|
4
|
-
function displayHelp() {
|
|
4
|
+
function displayHelp(exitCode: number = 0) {
|
|
5
5
|
console.log(`\nschema-codegen [path/to/Schema.ts]
|
|
6
6
|
|
|
7
7
|
Usage (C#/Unity)
|
|
@@ -22,7 +22,7 @@ ${Object.
|
|
|
22
22
|
Optional:
|
|
23
23
|
--namespace: generate namespace on output code
|
|
24
24
|
--decorator: custom name for @type decorator to scan for`);
|
|
25
|
-
process.exit();
|
|
25
|
+
process.exit(exitCode);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
const args = argv(process.argv.slice(2));
|
|
@@ -39,7 +39,7 @@ for (let target in generators) {
|
|
|
39
39
|
|
|
40
40
|
if (!args.output) {
|
|
41
41
|
console.error("You must provide a valid --output directory.");
|
|
42
|
-
displayHelp();
|
|
42
|
+
displayHelp(1);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
try {
|
|
@@ -55,5 +55,5 @@ try {
|
|
|
55
55
|
} catch (e) {
|
|
56
56
|
console.error(e.message);
|
|
57
57
|
console.error(e.stack);
|
|
58
|
-
displayHelp();
|
|
58
|
+
displayHelp(1);
|
|
59
59
|
}
|
package/src/codegen/parser.ts
CHANGED
|
@@ -339,6 +339,14 @@ export function parseFiles(
|
|
|
339
339
|
decoratorName: string = "type",
|
|
340
340
|
context: Context = new Context()
|
|
341
341
|
) {
|
|
342
|
+
if (typeof ts.createSourceFile !== "function") {
|
|
343
|
+
// typescript@7+ (native) no longer ships the JS compiler API
|
|
344
|
+
throw new Error(
|
|
345
|
+
`schema-codegen requires the TypeScript compiler API, which the installed "typescript@${(ts as any).version}" package does not provide.\n` +
|
|
346
|
+
`TypeScript 7+ no longer ships the JS compiler API — install typescript 5.x or 6.x (e.g. \`npm install --save-dev typescript@6\`) to use schema-codegen.`
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
|
|
342
350
|
/**
|
|
343
351
|
* Re-set globalContext for each test case
|
|
344
352
|
*/
|
|
@@ -389,7 +397,8 @@ export function parseFiles(
|
|
|
389
397
|
|
|
390
398
|
break;
|
|
391
399
|
} catch (e) {
|
|
392
|
-
//
|
|
400
|
+
// only swallow fs errors (ENOENT/EISDIR) while probing alternatives
|
|
401
|
+
if (!e?.code) { throw e; }
|
|
393
402
|
}
|
|
394
403
|
}
|
|
395
404
|
|
package/src/encoder/Encoder.ts
CHANGED
|
@@ -126,36 +126,23 @@ export class Encoder<T extends Schema = any> {
|
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
if (it.offset
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
if (it.offset <= buffer.byteLength) {
|
|
130
|
+
return buffer.subarray(0, it.offset);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Overflowed: grow and re-encode. Reuse the same iterator so `it.offset`
|
|
134
|
+
// ends accurate — a fresh one strands it at the overflow value and
|
|
135
|
+
// corrupts the next view's `viewOffset` in a multi-view encode.
|
|
136
|
+
buffer = this.ensureCapacity(buffer, it.offset);
|
|
133
137
|
|
|
134
|
-
|
|
138
|
+
console.warn(`@colyseus/schema buffer overflow. Encoded state is higher than default BUFFER_SIZE. Use the following to increase default BUFFER_SIZE:
|
|
135
139
|
|
|
136
140
|
import { Encoder } from "@colyseus/schema";
|
|
137
|
-
Encoder.BUFFER_SIZE = ${Math.round(
|
|
141
|
+
Encoder.BUFFER_SIZE = ${Math.round(buffer.byteLength / 1024)} * 1024; // ${Math.round(buffer.byteLength / 1024)} KB
|
|
138
142
|
`);
|
|
139
143
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
// -> No we probably can't unless we catch the need for resize before encoding which is likely more computationally expensive than resizing on demand
|
|
143
|
-
//
|
|
144
|
-
const newBuffer = new Uint8Array(newSize);
|
|
145
|
-
newBuffer.set(buffer); // copy previous encoding steps beyond the initialOffset
|
|
146
|
-
buffer = newBuffer;
|
|
147
|
-
|
|
148
|
-
// assign resized buffer to local sharedBuffer
|
|
149
|
-
if (buffer === this.sharedBuffer) {
|
|
150
|
-
this.sharedBuffer = buffer;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return this.encode({ offset: initialOffset }, view, buffer, changeSetName, isEncodeAll);
|
|
154
|
-
|
|
155
|
-
} else {
|
|
156
|
-
|
|
157
|
-
return buffer.subarray(0, it.offset);
|
|
158
|
-
}
|
|
144
|
+
it.offset = initialOffset;
|
|
145
|
+
return this.encode(it, view, buffer, changeSetName, isEncodeAll);
|
|
159
146
|
}
|
|
160
147
|
|
|
161
148
|
encodeAll(
|
|
@@ -173,8 +160,8 @@ export class Encoder<T extends Schema = any> {
|
|
|
173
160
|
) {
|
|
174
161
|
const viewOffset = it.offset;
|
|
175
162
|
|
|
176
|
-
//
|
|
177
|
-
this.encode(it, view, bytes, "allFilteredChanges", true, viewOffset);
|
|
163
|
+
// encode() may reallocate the buffer — keep its return, not the stale `bytes`.
|
|
164
|
+
bytes = this.encode(it, view, bytes, "allFilteredChanges", true, viewOffset);
|
|
178
165
|
|
|
179
166
|
return concatBytes(
|
|
180
167
|
bytes.subarray(0, sharedOffset),
|
|
@@ -182,6 +169,16 @@ export class Encoder<T extends Schema = any> {
|
|
|
182
169
|
);
|
|
183
170
|
}
|
|
184
171
|
|
|
172
|
+
/** Grow `buffer` to keep BUFFER_SIZE free bytes past `offset`, preserving `[0, offset)`. */
|
|
173
|
+
protected ensureCapacity(buffer: Uint8Array, offset: number): Uint8Array {
|
|
174
|
+
if (offset + Encoder.BUFFER_SIZE <= buffer.byteLength) { return buffer; }
|
|
175
|
+
const size = Math.ceil((offset + Encoder.BUFFER_SIZE) / Encoder.BUFFER_SIZE) * Encoder.BUFFER_SIZE;
|
|
176
|
+
const grown = new Uint8Array(size);
|
|
177
|
+
grown.set(buffer.subarray(0, offset));
|
|
178
|
+
if (buffer === this.sharedBuffer) { this.sharedBuffer = grown; }
|
|
179
|
+
return grown;
|
|
180
|
+
}
|
|
181
|
+
|
|
185
182
|
encodeView(
|
|
186
183
|
view: StateView,
|
|
187
184
|
sharedOffset: number,
|
|
@@ -232,6 +229,10 @@ export class Encoder<T extends Schema = any> {
|
|
|
232
229
|
const encoder = ctor[$encoder];
|
|
233
230
|
const metadata = ctor[Symbol.metadata];
|
|
234
231
|
|
|
232
|
+
// These writes are unguarded and unrecoverable (view.changes is cleared
|
|
233
|
+
// below), so unlike encode() they can't re-encode on overflow — grow ahead.
|
|
234
|
+
bytes = this.ensureCapacity(bytes, it.offset);
|
|
235
|
+
|
|
235
236
|
bytes[it.offset++] = SWITCH_TO_STRUCTURE & 255;
|
|
236
237
|
encode.number(bytes, ref[$refId], it);
|
|
237
238
|
|
|
@@ -255,8 +256,10 @@ export class Encoder<T extends Schema = any> {
|
|
|
255
256
|
view.changes.clear();
|
|
256
257
|
view.changesOutOfOrder = false;
|
|
257
258
|
|
|
258
|
-
//
|
|
259
|
-
|
|
259
|
+
// encode() may reallocate the buffer — keep its return, not the stale `bytes`.
|
|
260
|
+
// Anchor the re-encode at the current offset (default), not `viewOffset`: a
|
|
261
|
+
// resize must not clobber the view.changes already written at [viewOffset, ).
|
|
262
|
+
bytes = this.encode(it, view, bytes, "filteredChanges", false);
|
|
260
263
|
|
|
261
264
|
return concatBytes(
|
|
262
265
|
bytes.subarray(0, sharedOffset),
|