mcbe-ipc 3.1.4 → 3.2.1

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 CHANGED
@@ -23,4 +23,13 @@ npm install mcbe-ipc
23
23
 
24
24
 
25
25
 
26
+
27
+ > [!NOTE]
28
+ > Official documentation is still in progress.
29
+ >
30
+ > For now, you can refer to the [DeepWiki page](https://deepwiki.com/OmniacDev/MCBE-IPC/).
31
+ > Please note that while it is generally accurate, some of the more advanced sections may contain small inaccuracies.
32
+
33
+
34
+
26
35
  [^1]: Inter-Pack Communication
package/dist/ipc.d.ts CHANGED
@@ -23,12 +23,20 @@
23
23
  * SOFTWARE.
24
24
  */
25
25
  export declare namespace PROTO {
26
- interface Serializable<T> {
26
+ const t: unique symbol;
27
+ interface Phantom<T> {
28
+ readonly [t]?: T;
29
+ }
30
+ export interface Serializer<T> extends Phantom<T> {
27
31
  serialize(value: T, stream: Buffer): Generator<void, void, void>;
32
+ }
33
+ export interface Deserializer<T> extends Phantom<T> {
28
34
  deserialize(stream: Buffer): Generator<void, T, void>;
29
35
  }
30
- type Infer<S> = S extends PROTO.Serializable<infer T> ? T : never;
31
- class Buffer {
36
+ export interface Serializable<T> extends Serializer<T>, Deserializer<T> {
37
+ }
38
+ export type Infer<S> = S extends Phantom<infer T> ? T : never;
39
+ export class Buffer {
32
40
  private _buffer;
33
41
  private _data_view;
34
42
  private _length;
@@ -37,71 +45,75 @@ export declare namespace PROTO {
37
45
  get front(): number;
38
46
  get data_view(): DataView;
39
47
  constructor(size?: number);
40
- write_byte(byte: number): void;
41
- write_bytes(bytes: Uint8Array): void;
42
- read_byte(): number;
43
- read_bytes(amount: number): Uint8Array;
48
+ reserve(amount: number): number;
49
+ consume(amount: number): number;
50
+ write(byte: number): void;
51
+ write(bytes: Uint8Array): void;
52
+ read(): number;
53
+ read(amount: number): Uint8Array;
44
54
  ensure_capacity(size: number): void;
45
55
  static from_uint8array(array: Uint8Array): Buffer;
46
56
  to_uint8array(): Uint8Array;
47
57
  }
48
- namespace MIPS {
58
+ export namespace MIPS {
49
59
  function serialize(stream: PROTO.Buffer): Generator<void, string, void>;
50
60
  function deserialize(str: string): Generator<void, PROTO.Buffer, void>;
51
61
  }
52
- const Void: PROTO.Serializable<void>;
53
- const Null: PROTO.Serializable<null>;
54
- const Undefined: PROTO.Serializable<undefined>;
55
- const Int8: PROTO.Serializable<number>;
56
- const Int16: PROTO.Serializable<number>;
57
- const Int32: PROTO.Serializable<number>;
58
- const UInt8: PROTO.Serializable<number>;
59
- const UInt16: PROTO.Serializable<number>;
60
- const UInt32: PROTO.Serializable<number>;
61
- const UVarInt32: PROTO.Serializable<number>;
62
- const Float32: PROTO.Serializable<number>;
63
- const Float64: PROTO.Serializable<number>;
64
- const String: PROTO.Serializable<string>;
65
- const Boolean: PROTO.Serializable<boolean>;
66
- const UInt8Array: PROTO.Serializable<Uint8Array>;
67
- const Date: PROTO.Serializable<Date>;
68
- function Object<T extends object>(obj: {
62
+ export const Void: PROTO.Serializable<void>;
63
+ export const Null: PROTO.Serializable<null>;
64
+ export const Undefined: PROTO.Serializable<undefined>;
65
+ export const Int8: PROTO.Serializable<number>;
66
+ export const Int16: PROTO.Serializable<number>;
67
+ export const Int32: PROTO.Serializable<number>;
68
+ export const UInt8: PROTO.Serializable<number>;
69
+ export const UInt16: PROTO.Serializable<number>;
70
+ export const UInt32: PROTO.Serializable<number>;
71
+ export const UVarInt32: PROTO.Serializable<number>;
72
+ export const VarInt32: PROTO.Serializable<number>;
73
+ export const Float32: PROTO.Serializable<number>;
74
+ export const Float64: PROTO.Serializable<number>;
75
+ export const String: PROTO.Serializable<string>;
76
+ export const Boolean: PROTO.Serializable<boolean>;
77
+ export const UInt8Array: PROTO.Serializable<Uint8Array>;
78
+ export const Date: PROTO.Serializable<Date>;
79
+ export function Object<T extends object>(s: {
69
80
  [K in keyof T]: PROTO.Serializable<T[K]>;
70
81
  }): PROTO.Serializable<T>;
71
- function Array<T>(value: PROTO.Serializable<T>): PROTO.Serializable<T[]>;
72
- function Tuple<T extends any[]>(...values: {
82
+ export function Array<T>(s: PROTO.Serializable<T>): PROTO.Serializable<T[]>;
83
+ export function Tuple<T extends any[]>(...s: {
73
84
  [K in keyof T]: PROTO.Serializable<T[K]>;
74
85
  }): PROTO.Serializable<T>;
75
- function Optional<T>(value: PROTO.Serializable<T>): PROTO.Serializable<T | undefined>;
76
- function Map<K, V>(key: PROTO.Serializable<K>, value: PROTO.Serializable<V>): PROTO.Serializable<Map<K, V>>;
77
- function Set<V>(value: PROTO.Serializable<V>): PROTO.Serializable<Set<V>>;
78
- type Endpoint = string;
79
- type Header = {
86
+ export function Optional<T>(s: PROTO.Serializable<T>): PROTO.Serializable<T | undefined>;
87
+ export function Map<K, V>(kS: PROTO.Serializable<K>, vS: PROTO.Serializable<V>): PROTO.Serializable<Map<K, V>>;
88
+ export function Set<V>(s: PROTO.Serializable<V>): PROTO.Serializable<Set<V>>;
89
+ export type Endpoint = string;
90
+ export type Header = {
80
91
  guid: string;
81
92
  encoding: string;
82
93
  index: number;
83
94
  final: boolean;
84
95
  };
85
- const Endpoint: PROTO.Serializable<Endpoint>;
86
- const Header: PROTO.Serializable<Header>;
96
+ export const Endpoint: PROTO.Serializable<Endpoint>;
97
+ export const Header: PROTO.Serializable<Header>;
98
+ export {};
87
99
  }
88
100
  export declare namespace NET {
89
101
  let FRAG_MAX: number;
90
102
  function serialize(buffer: PROTO.Buffer, max_size?: number): Generator<void, string[], void>;
91
103
  function deserialize(strings: string[]): Generator<void, PROTO.Buffer, void>;
92
- function emit<S extends PROTO.Serializable<any>>(endpoint: string, serializer: S, value: PROTO.Infer<S>): Generator<void, void, void>;
93
- function listen<S extends PROTO.Serializable<any>>(endpoint: string, serializer: S, callback: (value: PROTO.Infer<S>) => Generator<void, void, void>): () => void;
104
+ function emit<S extends PROTO.Serializer<any>>(endpoint: string, serializer: S, value: PROTO.Infer<S>): Generator<void, void, void>;
105
+ function listen<D extends PROTO.Deserializer<any>>(endpoint: string, deserializer: D, callback: (value: PROTO.Infer<D>) => Generator<void, void, void>): () => void;
94
106
  }
95
107
  export declare namespace IPC {
96
108
  /** Sends a message with `args` to `channel` */
97
- function send<S extends PROTO.Serializable<any>>(channel: string, serializer: S, value: PROTO.Infer<S>): void;
109
+ function send<S extends PROTO.Serializer<any>>(channel: string, serializer: S, value: PROTO.Infer<S>): void;
98
110
  /** Sends an `invoke` message through IPC, and expects a result asynchronously. */
99
- function invoke<S extends PROTO.Serializable<any>, D extends PROTO.Serializable<any>>(channel: string, serializer: S, value: PROTO.Infer<S>, deserializer: S): Promise<PROTO.Infer<D>>;
111
+ function invoke<S extends PROTO.Serializer<any>, D extends PROTO.Deserializer<any>>(channel: string, serializer: S, value: PROTO.Infer<S>, deserializer: D): Promise<PROTO.Infer<D>>;
100
112
  /** Listens to `channel`. When a new message arrives, `listener` will be called with `listener(args)`. */
101
- function on<D extends PROTO.Serializable<any>>(channel: string, deserializer: D, listener: (value: PROTO.Infer<D>) => void): () => void;
113
+ function on<D extends PROTO.Deserializer<any>>(channel: string, deserializer: D, listener: (value: PROTO.Infer<D>) => void): () => void;
102
114
  /** Listens to `channel` once. When a new message arrives, `listener` will be called with `listener(args)`, and then removed. */
103
- function once<D extends PROTO.Serializable<any>>(channel: string, deserializer: D, listener: (value: PROTO.Infer<D>) => void): () => void;
115
+ function once<D extends PROTO.Deserializer<any>>(channel: string, deserializer: D, listener: (value: PROTO.Infer<D>) => void): () => void;
104
116
  /** Adds a handler for an `invoke` IPC. This handler will be called whenever `invoke(channel, ...args)` is called */
105
- function handle<D extends PROTO.Serializable<any>, S extends PROTO.Serializable<any>>(channel: string, deserializer: D, serializer: S, listener: (value: PROTO.Infer<D>) => PROTO.Infer<S>): () => void;
117
+ function handle<D extends PROTO.Deserializer<any>, S extends PROTO.Serializer<any>>(channel: string, deserializer: D, serializer: S, listener: (value: PROTO.Infer<D>) => PROTO.Infer<S>): () => void;
106
118
  }
107
119
  export default IPC;
package/dist/ipc.js CHANGED
@@ -41,31 +41,39 @@ export var PROTO;
41
41
  this._length = 0;
42
42
  this._offset = 0;
43
43
  }
44
- write_byte(byte) {
45
- this.ensure_capacity(1);
46
- this._buffer[this.end] = byte;
47
- this._length++;
48
- }
49
- write_bytes(bytes) {
50
- this.ensure_capacity(bytes.length);
51
- this._buffer.set(bytes, this.end);
52
- this._length += bytes.length;
53
- }
54
- read_byte() {
55
- const byte = this._buffer[this._offset];
56
- this._length--;
57
- this._offset++;
58
- return byte;
59
- }
60
- read_bytes(amount) {
61
- if (this._length > 0) {
62
- const max_amount = amount > this._length ? this._length : amount;
63
- const values = this._buffer.slice(this._offset, this._offset + max_amount);
64
- this._length -= max_amount;
65
- this._offset += max_amount;
66
- return values;
44
+ reserve(amount) {
45
+ this.ensure_capacity(amount);
46
+ const end = this.end;
47
+ this._length += amount;
48
+ return end;
49
+ }
50
+ consume(amount) {
51
+ if (amount > this._length)
52
+ throw new Error('not enough bytes');
53
+ const front = this.front;
54
+ this._length -= amount;
55
+ this._offset += amount;
56
+ return front;
57
+ }
58
+ write(input) {
59
+ if (typeof input === 'number') {
60
+ const offset = this.reserve(1);
61
+ this._buffer[offset] = input;
62
+ }
63
+ else {
64
+ const offset = this.reserve(input.length);
65
+ this._buffer.set(input, offset);
66
+ }
67
+ }
68
+ read(amount) {
69
+ if (amount === undefined) {
70
+ const offset = this.consume(1);
71
+ return this._buffer[offset];
72
+ }
73
+ else {
74
+ const offset = this.consume(amount);
75
+ return this._buffer.slice(offset, offset + amount);
67
76
  }
68
- return new Uint8Array();
69
77
  }
70
78
  ensure_capacity(size) {
71
79
  if (this.end + size > this._buffer.length) {
@@ -109,7 +117,7 @@ export var PROTO;
109
117
  const hex_str = str.slice(3, str.length - 1);
110
118
  for (let i = 0; i < hex_str.length; i++) {
111
119
  const hex = hex_str[i] + hex_str[++i];
112
- buffer.write_byte(parseInt(hex, 16));
120
+ buffer.write(parseInt(hex, 16));
113
121
  yield;
114
122
  }
115
123
  return buffer;
@@ -136,120 +144,98 @@ export var PROTO;
136
144
  };
137
145
  PROTO.Int8 = {
138
146
  *serialize(value, stream) {
139
- const length = 1;
140
- stream.write_bytes(new Uint8Array(length));
141
- stream.data_view.setInt8(stream.end - length, value);
147
+ stream.data_view.setInt8(stream.reserve(1), value);
142
148
  },
143
149
  *deserialize(stream) {
144
- const value = stream.data_view.getInt8(stream.front);
145
- stream.read_bytes(1);
146
- return value;
150
+ return stream.data_view.getInt8(stream.consume(1));
147
151
  }
148
152
  };
149
153
  PROTO.Int16 = {
150
154
  *serialize(value, stream) {
151
- const length = 2;
152
- stream.write_bytes(new Uint8Array(length));
153
- stream.data_view.setInt16(stream.end - length, value);
155
+ stream.data_view.setInt16(stream.reserve(2), value);
154
156
  },
155
157
  *deserialize(stream) {
156
- const value = stream.data_view.getInt16(stream.front);
157
- stream.read_bytes(2);
158
- return value;
158
+ return stream.data_view.getInt16(stream.consume(2));
159
159
  }
160
160
  };
161
161
  PROTO.Int32 = {
162
162
  *serialize(value, stream) {
163
- const length = 4;
164
- stream.write_bytes(new Uint8Array(length));
165
- stream.data_view.setInt32(stream.end - length, value);
163
+ stream.data_view.setInt32(stream.reserve(4), value);
166
164
  },
167
165
  *deserialize(stream) {
168
- const value = stream.data_view.getInt32(stream.front);
169
- stream.read_bytes(4);
170
- return value;
166
+ return stream.data_view.getInt32(stream.consume(4));
171
167
  }
172
168
  };
173
169
  PROTO.UInt8 = {
174
170
  *serialize(value, stream) {
175
- const length = 1;
176
- stream.write_bytes(new Uint8Array(length));
177
- stream.data_view.setUint8(stream.end - length, value);
171
+ stream.data_view.setUint8(stream.reserve(1), value);
178
172
  },
179
173
  *deserialize(stream) {
180
- const value = stream.data_view.getUint8(stream.front);
181
- stream.read_bytes(1);
182
- return value;
174
+ return stream.data_view.getUint8(stream.consume(1));
183
175
  }
184
176
  };
185
177
  PROTO.UInt16 = {
186
178
  *serialize(value, stream) {
187
- const length = 2;
188
- stream.write_bytes(new Uint8Array(length));
189
- stream.data_view.setUint16(stream.end - length, value);
179
+ stream.data_view.setUint16(stream.reserve(2), value);
190
180
  },
191
181
  *deserialize(stream) {
192
- const value = stream.data_view.getUint16(stream.front);
193
- stream.read_bytes(2);
194
- return value;
182
+ return stream.data_view.getUint16(stream.consume(2));
195
183
  }
196
184
  };
197
185
  PROTO.UInt32 = {
198
186
  *serialize(value, stream) {
199
- const length = 4;
200
- stream.write_bytes(new Uint8Array(length));
201
- stream.data_view.setUint32(stream.end - length, value);
187
+ stream.data_view.setUint32(stream.reserve(4), value);
202
188
  },
203
189
  *deserialize(stream) {
204
- const value = stream.data_view.getUint32(stream.front);
205
- stream.read_bytes(4);
206
- return value;
190
+ return stream.data_view.getUint32(stream.consume(4));
207
191
  }
208
192
  };
209
193
  PROTO.UVarInt32 = {
210
194
  *serialize(value, stream) {
195
+ value >>>= 0;
211
196
  while (value >= 0x80) {
212
- stream.write_byte((value & 0x7f) | 0x80);
213
- value >>= 7;
197
+ stream.write((value & 0x7f) | 0x80);
198
+ value >>>= 7;
214
199
  yield;
215
200
  }
216
- stream.write_byte(value);
201
+ stream.write(value);
217
202
  },
218
203
  *deserialize(stream) {
219
204
  let value = 0;
220
- let size = 0;
221
- let byte;
222
- do {
223
- byte = stream.read_byte();
205
+ for (let size = 0; size < 5; size++) {
206
+ const byte = stream.read();
224
207
  value |= (byte & 0x7f) << (size * 7);
225
- size += 1;
226
208
  yield;
227
- } while ((byte & 0x80) !== 0 && size < 10);
228
- return value;
209
+ if ((byte & 0x80) == 0)
210
+ break;
211
+ }
212
+ return value >>> 0;
213
+ }
214
+ };
215
+ PROTO.VarInt32 = {
216
+ *serialize(value, stream) {
217
+ const zigzag = (value << 1) ^ (value >> 31);
218
+ yield* PROTO.UVarInt32.serialize(zigzag, stream);
219
+ },
220
+ *deserialize(stream) {
221
+ const zigzag = yield* PROTO.UVarInt32.deserialize(stream);
222
+ return (zigzag >>> 1) ^ -(zigzag & 1);
229
223
  }
230
224
  };
231
225
  PROTO.Float32 = {
232
226
  *serialize(value, stream) {
233
- const length = 4;
234
- stream.write_bytes(new Uint8Array(length));
235
- stream.data_view.setFloat32(stream.end - length, value);
227
+ stream.data_view.setFloat32(stream.reserve(4), value);
236
228
  },
237
229
  *deserialize(stream) {
238
- const value = stream.data_view.getFloat32(stream.front);
239
- stream.read_bytes(4);
240
- return value;
230
+ return stream.data_view.getFloat32(stream.consume(4));
241
231
  }
242
232
  };
243
233
  PROTO.Float64 = {
244
234
  *serialize(value, stream) {
245
- const length = 8;
246
- stream.write_bytes(new Uint8Array(length));
247
- stream.data_view.setFloat64(stream.end - length, value);
235
+ stream.data_view.setFloat64(stream.reserve(8), value);
248
236
  },
249
237
  *deserialize(stream) {
250
- const value = stream.data_view.getFloat64(stream.front);
251
- stream.read_bytes(8);
252
- return value;
238
+ return stream.data_view.getFloat64(stream.consume(8));
253
239
  }
254
240
  };
255
241
  PROTO.String = {
@@ -272,21 +258,20 @@ export var PROTO;
272
258
  };
273
259
  PROTO.Boolean = {
274
260
  *serialize(value, stream) {
275
- stream.write_byte(value ? 1 : 0);
261
+ stream.write(value ? 1 : 0);
276
262
  },
277
263
  *deserialize(stream) {
278
- const value = stream.read_byte();
279
- return value === 1;
264
+ return stream.read() !== 0;
280
265
  }
281
266
  };
282
267
  PROTO.UInt8Array = {
283
268
  *serialize(value, stream) {
284
269
  yield* PROTO.UVarInt32.serialize(value.length, stream);
285
- stream.write_bytes(value);
270
+ stream.write(value);
286
271
  },
287
272
  *deserialize(stream) {
288
273
  const length = yield* PROTO.UVarInt32.deserialize(stream);
289
- return stream.read_bytes(length);
274
+ return stream.read(length);
290
275
  }
291
276
  };
292
277
  PROTO.Date = {
@@ -297,92 +282,91 @@ export var PROTO;
297
282
  return new globalThis.Date(yield* PROTO.Float64.deserialize(stream));
298
283
  }
299
284
  };
300
- function Object(obj) {
285
+ function Object(s) {
301
286
  return {
302
287
  *serialize(value, stream) {
303
- for (const key in obj) {
304
- yield* obj[key].serialize(value[key], stream);
288
+ for (const key in s) {
289
+ yield* s[key].serialize(value[key], stream);
305
290
  }
306
291
  },
307
292
  *deserialize(stream) {
308
293
  const result = {};
309
- for (const key in obj) {
310
- result[key] = yield* obj[key].deserialize(stream);
294
+ for (const key in s) {
295
+ result[key] = yield* s[key].deserialize(stream);
311
296
  }
312
297
  return result;
313
298
  }
314
299
  };
315
300
  }
316
301
  PROTO.Object = Object;
317
- function Array(value) {
302
+ function Array(s) {
318
303
  return {
319
- *serialize(array, stream) {
320
- yield* PROTO.UVarInt32.serialize(array.length, stream);
321
- for (const item of array) {
322
- yield* value.serialize(item, stream);
304
+ *serialize(value, stream) {
305
+ yield* PROTO.UVarInt32.serialize(value.length, stream);
306
+ for (const item of value) {
307
+ yield* s.serialize(item, stream);
323
308
  }
324
309
  },
325
310
  *deserialize(stream) {
326
311
  const result = [];
327
312
  const length = yield* PROTO.UVarInt32.deserialize(stream);
328
313
  for (let i = 0; i < length; i++) {
329
- result[i] = yield* value.deserialize(stream);
314
+ result[i] = yield* s.deserialize(stream);
330
315
  }
331
316
  return result;
332
317
  }
333
318
  };
334
319
  }
335
320
  PROTO.Array = Array;
336
- function Tuple(...values) {
321
+ function Tuple(...s) {
337
322
  return {
338
- *serialize(tuple, stream) {
339
- for (let i = 0; i < values.length; i++) {
340
- yield* values[i].serialize(tuple[i], stream);
323
+ *serialize(value, stream) {
324
+ for (let i = 0; i < s.length; i++) {
325
+ yield* s[i].serialize(value[i], stream);
341
326
  }
342
327
  },
343
328
  *deserialize(stream) {
344
329
  const result = [];
345
- for (let i = 0; i < values.length; i++) {
346
- result[i] = yield* values[i].deserialize(stream);
330
+ for (let i = 0; i < s.length; i++) {
331
+ result[i] = yield* s[i].deserialize(stream);
347
332
  }
348
333
  return result;
349
334
  }
350
335
  };
351
336
  }
352
337
  PROTO.Tuple = Tuple;
353
- function Optional(value) {
338
+ function Optional(s) {
354
339
  return {
355
- *serialize(optional, stream) {
356
- yield* PROTO.Boolean.serialize(optional !== undefined, stream);
357
- if (optional !== undefined) {
358
- yield* value.serialize(optional, stream);
359
- }
340
+ *serialize(value, stream) {
341
+ const def = value !== undefined;
342
+ yield* PROTO.Boolean.serialize(def, stream);
343
+ if (def)
344
+ yield* s.serialize(value, stream);
360
345
  },
361
346
  *deserialize(stream) {
362
- const defined = yield* PROTO.Boolean.deserialize(stream);
363
- if (defined) {
364
- return yield* value.deserialize(stream);
365
- }
347
+ const def = yield* PROTO.Boolean.deserialize(stream);
348
+ if (def)
349
+ return yield* s.deserialize(stream);
366
350
  return undefined;
367
351
  }
368
352
  };
369
353
  }
370
354
  PROTO.Optional = Optional;
371
- function Map(key, value) {
355
+ function Map(kS, vS) {
372
356
  return {
373
- *serialize(map, stream) {
374
- yield* PROTO.UVarInt32.serialize(map.size, stream);
375
- for (const [k, v] of map.entries()) {
376
- yield* key.serialize(k, stream);
377
- yield* value.serialize(v, stream);
357
+ *serialize(value, stream) {
358
+ yield* PROTO.UVarInt32.serialize(value.size, stream);
359
+ for (const [k, v] of value) {
360
+ yield* kS.serialize(k, stream);
361
+ yield* vS.serialize(v, stream);
378
362
  }
379
363
  },
380
364
  *deserialize(stream) {
381
365
  const size = yield* PROTO.UVarInt32.deserialize(stream);
382
366
  const result = new globalThis.Map();
383
367
  for (let i = 0; i < size; i++) {
384
- const k = yield* key.deserialize(stream);
385
- const v = yield* value.deserialize(stream);
368
+ const k = yield* kS.deserialize(stream);
369
+ const v = yield* vS.deserialize(stream);
386
370
  result.set(k, v);
387
371
  }
388
372
  return result;
@@ -390,19 +374,19 @@ export var PROTO;
390
374
  };
391
375
  }
392
376
  PROTO.Map = Map;
393
- function Set(value) {
377
+ function Set(s) {
394
378
  return {
395
379
  *serialize(set, stream) {
396
380
  yield* PROTO.UVarInt32.serialize(set.size, stream);
397
- for (const [_, v] of set.entries()) {
398
- yield* value.serialize(v, stream);
381
+ for (const v of set) {
382
+ yield* s.serialize(v, stream);
399
383
  }
400
384
  },
401
385
  *deserialize(stream) {
402
386
  const size = yield* PROTO.UVarInt32.deserialize(stream);
403
387
  const result = new globalThis.Set();
404
388
  for (let i = 0; i < size; i++) {
405
- const v = yield* value.deserialize(stream);
389
+ const v = yield* s.deserialize(stream);
406
390
  result.add(v);
407
391
  }
408
392
  return result;
@@ -460,12 +444,12 @@ export var NET;
460
444
  if (char_code <= 0xff) {
461
445
  const hex = str[j] + str[++j];
462
446
  const hex_code = parseInt(hex, 16);
463
- buffer.write_byte(hex_code & 0xff);
464
- buffer.write_byte(hex_code >> 8);
447
+ buffer.write(hex_code & 0xff);
448
+ buffer.write(hex_code >> 8);
465
449
  }
466
450
  else {
467
- buffer.write_byte(char_code & 0xff);
468
- buffer.write_byte(char_code >> 8);
451
+ buffer.write(char_code & 0xff);
452
+ buffer.write(char_code >> 8);
469
453
  }
470
454
  yield;
471
455
  }
@@ -476,16 +460,26 @@ export var NET;
476
460
  NET.deserialize = deserialize;
477
461
  system.afterEvents.scriptEventReceive.subscribe(event => {
478
462
  system.runJob((function* () {
463
+ if (event.sourceType !== ScriptEventSource.Server)
464
+ return;
479
465
  const [serialized_endpoint, serialized_header] = event.id.split(':');
480
466
  const endpoint_stream = yield* PROTO.MIPS.deserialize(serialized_endpoint);
481
467
  const endpoint = yield* PROTO.Endpoint.deserialize(endpoint_stream);
482
468
  const listeners = ENDPOINTS.get(endpoint);
483
- if (event.sourceType === ScriptEventSource.Server && listeners) {
469
+ if (listeners !== undefined) {
484
470
  const header_stream = yield* PROTO.MIPS.deserialize(serialized_header);
485
471
  const header = yield* PROTO.Header.deserialize(header_stream);
472
+ const errors = [];
486
473
  for (let i = 0; i < listeners.length; i++) {
487
- yield* listeners[i](header, event.message);
474
+ try {
475
+ yield* listeners[i](header, event.message);
476
+ }
477
+ catch (e) {
478
+ errors.push(e);
479
+ }
488
480
  }
481
+ if (errors.length > 0)
482
+ throw new AggregateError(errors, 'one or more listeners failed');
489
483
  }
490
484
  })());
491
485
  });
@@ -530,7 +524,7 @@ export var NET;
530
524
  }
531
525
  }
532
526
  NET.emit = emit;
533
- function listen(endpoint, serializer, callback) {
527
+ function listen(endpoint, deserializer, callback) {
534
528
  const buffer = new Map();
535
529
  const listener = function* (payload, serialized_packet) {
536
530
  let fragment = buffer.get(payload.guid);
@@ -545,7 +539,7 @@ export var NET;
545
539
  fragment.data_size += payload.index + 1;
546
540
  if (fragment.size !== -1 && fragment.data_size === (fragment.size * (fragment.size + 1)) / 2) {
547
541
  const stream = yield* deserialize(fragment.serialized_packets);
548
- const value = yield* serializer.deserialize(stream);
542
+ const value = yield* deserializer.deserialize(stream);
549
543
  yield* callback(value);
550
544
  buffer.delete(payload.guid);
551
545
  }
@@ -563,12 +557,12 @@ export var IPC;
563
557
  IPC.send = send;
564
558
  /** Sends an `invoke` message through IPC, and expects a result asynchronously. */
565
559
  function invoke(channel, serializer, value, deserializer) {
566
- system.runJob(NET.emit(`ipc:${channel}:invoke`, serializer, value));
567
560
  return new Promise(resolve => {
568
561
  const terminate = NET.listen(`ipc:${channel}:handle`, deserializer, function* (value) {
569
562
  resolve(value);
570
563
  terminate();
571
564
  });
565
+ system.runJob(NET.emit(`ipc:${channel}:invoke`, serializer, value));
572
566
  });
573
567
  }
574
568
  IPC.invoke = invoke;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "author": "OmniacDev",
4
4
  "description": "IPC system for MCBE Script API projects",
5
5
  "license": "MIT",
6
- "version": "3.1.4",
6
+ "version": "3.2.1",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "git+https://github.com/OmniacDev/MCBE-IPC.git"
@@ -20,12 +20,15 @@
20
20
  ],
21
21
  "scripts": {
22
22
  "build": "tsc",
23
+ "test": "vitest",
24
+ "bench": "vitest bench",
23
25
  "format": "prettier --write src",
24
26
  "prepublishOnly": "npm run build"
25
27
  },
26
28
  "devDependencies": {
27
29
  "prettier": "^3.3.3",
28
- "typescript": "^5.5.4"
30
+ "typescript": "^5.5.4",
31
+ "vitest": "^4.0.16"
29
32
  },
30
33
  "dependencies": {
31
34
  "@minecraft/server": "^1.18.0"