isaacscript-common 6.10.0 → 6.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -32,6 +32,12 @@ export function runDeepCopyTests(): void {
32
32
  copiedDefaultMapHasChildDefaultMap();
33
33
  copiedDefaultMapHasBrand();
34
34
 
35
+ copiedSerializedMapHasStringKey();
36
+ copiedSerializedMapHasNumberKey();
37
+
38
+ copiedSerializedDefaultMapHasStringKey();
39
+ copiedSerializedDefaultMapHasNumberKey();
40
+
35
41
  log("All deep copy tests passed!");
36
42
  }
37
43
 
@@ -268,11 +274,8 @@ function copiedMapIsMap() {
268
274
  const newObject = deepCopy(oldMap, SerializationType.NONE, "copiedMapIsMap");
269
275
  const newMap = newObject as Map<string, string>;
270
276
 
271
- if (!isTable(newMap)) {
272
- error(`The copied Map had a type of: ${typeof newMap}`);
273
- }
274
277
  if (!isTSTLMap(newMap)) {
275
- error("The copied Map was not a Map.");
278
+ error(`The copied Map was not a Map and has a type of: ${typeof newMap}`);
276
279
  }
277
280
  }
278
281
 
@@ -287,8 +290,13 @@ function copiedMapHasValue() {
287
290
  SerializationType.NONE,
288
291
  "copiedMapHasValue",
289
292
  );
293
+
290
294
  const newMap = newTable as typeof oldMap;
291
295
 
296
+ if (!isTSTLMap(newMap)) {
297
+ error(`The copied Map was not a Map and has a type of: ${typeof newMap}`);
298
+ }
299
+
292
300
  const value = newMap.get(keyToLookFor);
293
301
  if (value === undefined) {
294
302
  error(`The copied Map did not have a key of: ${keyToLookFor}`);
@@ -306,11 +314,8 @@ function copiedSetIsSet() {
306
314
  const newTable = deepCopy(oldSet, SerializationType.NONE, "copiedSetIsSet");
307
315
  const newSet = newTable as Set<string>;
308
316
 
309
- if (!isTable(newSet)) {
310
- error(`The copied Set had a type of: ${typeof newSet}`);
311
- }
312
317
  if (!isTSTLSet(newSet)) {
313
- error("The copied Set was not a Map.");
318
+ error(`The copied Set was not a Set and has a type of: ${typeof newSet}`);
314
319
  }
315
320
  }
316
321
 
@@ -326,6 +331,10 @@ function copiedSetHasValue() {
326
331
  );
327
332
  const newSet = newTable as Set<string>;
328
333
 
334
+ if (!isTSTLSet(newSet)) {
335
+ error(`The copied Set was not a Set and has a type of: ${typeof newSet}`);
336
+ }
337
+
329
338
  const hasValue = newSet.has(valueToLookFor);
330
339
  if (!hasValue) {
331
340
  error(`The copied Set did not have a value of: ${valueToLookFor}`);
@@ -338,7 +347,7 @@ function copiedMapHasChildMap() {
338
347
  const oldChildMap = new Map<number, number>();
339
348
  oldChildMap.set(childMapKey, childMapValue);
340
349
 
341
- const keyToLookFor = "abc";
350
+ const keyToLookFor = "childMap";
342
351
  const oldMap = new Map<string, Map<number, number>>();
343
352
  oldMap.set(keyToLookFor, oldChildMap);
344
353
 
@@ -349,16 +358,19 @@ function copiedMapHasChildMap() {
349
358
  );
350
359
  const newMap = newTable as typeof oldMap;
351
360
 
361
+ if (!isTSTLMap(newMap)) {
362
+ error(`The copied Map was not a Map and had a type of: ${typeof newMap}`);
363
+ }
364
+
352
365
  const newChildMap = newMap.get(keyToLookFor);
353
366
  if (newChildMap === undefined) {
354
367
  error(`The copied Map did not have a child map at key: ${keyToLookFor}`);
355
368
  }
356
369
 
357
- if (!isTable(newChildMap)) {
358
- error(`The copied child Map had a type of: ${typeof newChildMap}`);
359
- }
360
370
  if (!isTSTLMap(newChildMap)) {
361
- error("The copied child Map was not a Map.");
371
+ error(
372
+ `The copied child Map was not a Map and had a type of: ${typeof newChildMap}`,
373
+ );
362
374
  }
363
375
 
364
376
  const value = newChildMap.get(childMapKey);
@@ -390,6 +402,12 @@ function copiedDefaultMapHasChildDefaultMap() {
390
402
  );
391
403
  const newParentMap = newTable as typeof oldParentMap;
392
404
 
405
+ if (!isDefaultMap(newParentMap)) {
406
+ error(
407
+ `The copied parent DefaultMap was not a DefaultMap and had a type of: ${typeof newParentMap}`,
408
+ );
409
+ }
410
+
393
411
  const newChildMap = newParentMap.get(parentMapKey);
394
412
  if (newChildMap === undefined) {
395
413
  error(
@@ -397,11 +415,10 @@ function copiedDefaultMapHasChildDefaultMap() {
397
415
  );
398
416
  }
399
417
 
400
- if (!isTable(newChildMap)) {
401
- error(`The copied child DefaultMap had a type of: ${typeof newChildMap}`);
402
- }
403
418
  if (!isDefaultMap(newChildMap)) {
404
- error("The copied child DefaultMap was not a DefaultMap.");
419
+ error(
420
+ `The copied child DefaultMap was not a DefaultMap and had a type of: ${typeof newChildMap}`,
421
+ );
405
422
  }
406
423
 
407
424
  const newChildMapValue1 = newChildMap.get(childMapKey1);
@@ -434,9 +451,121 @@ function copiedDefaultMapHasBrand() {
434
451
  "copiedDefaultMapHasBrand",
435
452
  ) as LuaMap<AnyNotNil, unknown>;
436
453
 
454
+ if (!isTable(newTable)) {
455
+ error(
456
+ `The copied DefaultMap was not a table and had a type of: ${typeof newTable}`,
457
+ );
458
+ }
459
+
437
460
  if (!newTable.has(SerializationBrand.DEFAULT_MAP)) {
438
461
  error(
439
462
  `The copied DefaultMap does not have the brand: ${SerializationBrand.DEFAULT_MAP}`,
440
463
  );
441
464
  }
442
465
  }
466
+
467
+ function copiedSerializedMapHasStringKey() {
468
+ const mapKey = "123";
469
+ const mapValue = 456;
470
+ const oldMap = new Map<string, number>();
471
+ oldMap.set(mapKey, mapValue);
472
+
473
+ const serializedOldMap = deepCopy(
474
+ oldMap,
475
+ SerializationType.SERIALIZE,
476
+ "copiedSerializedMapHasStringKey-serialize",
477
+ );
478
+
479
+ const newTable = deepCopy(
480
+ serializedOldMap,
481
+ SerializationType.DESERIALIZE,
482
+ "copiedSerializedMapHasStringKey-deserialize",
483
+ );
484
+
485
+ const newMap = newTable as Map<string, number>;
486
+ if (!newMap.has(mapKey)) {
487
+ const keyType = type(mapKey);
488
+ error(
489
+ `The copied Map did not have a key of: ${mapKey} with type ${keyType}`,
490
+ );
491
+ }
492
+ }
493
+
494
+ function copiedSerializedMapHasNumberKey() {
495
+ const mapKey = 123;
496
+ const mapValue = 456;
497
+ const oldMap = new Map<number, number>();
498
+ oldMap.set(mapKey, mapValue);
499
+
500
+ const serializedOldMap = deepCopy(
501
+ oldMap,
502
+ SerializationType.SERIALIZE,
503
+ "copiedSerializedMapHasNumberKey-serialize",
504
+ );
505
+
506
+ const newTable = deepCopy(
507
+ serializedOldMap,
508
+ SerializationType.DESERIALIZE,
509
+ "copiedSerializedMapHasNumberKey-deserialize",
510
+ );
511
+
512
+ const newMap = newTable as Map<number, number>;
513
+ if (!newMap.has(mapKey)) {
514
+ const keyType = type(mapKey);
515
+ error(
516
+ `The copied Map did not have a key of: ${mapKey} with type ${keyType}`,
517
+ );
518
+ }
519
+ }
520
+
521
+ function copiedSerializedDefaultMapHasStringKey() {
522
+ const mapKey = "123";
523
+ const oldDefaultMap = new DefaultMap<string, number>(456);
524
+ oldDefaultMap.getAndSetDefault(mapKey);
525
+
526
+ const serializedOldDefaultMap = deepCopy(
527
+ oldDefaultMap,
528
+ SerializationType.SERIALIZE,
529
+ "copiedSerializedDefaultMapHasStringKey-serialize",
530
+ );
531
+
532
+ const newTable = deepCopy(
533
+ serializedOldDefaultMap,
534
+ SerializationType.DESERIALIZE,
535
+ "copiedSerializedDefaultMapHasStringKey-deserialize",
536
+ );
537
+
538
+ const newDefaultMap = newTable as DefaultMap<string, number>;
539
+ if (!newDefaultMap.has(mapKey)) {
540
+ const keyType = type(mapKey);
541
+ error(
542
+ `The copied DefaultMap did not have a key of "${mapKey}" with type: ${keyType}`,
543
+ );
544
+ }
545
+ }
546
+
547
+ function copiedSerializedDefaultMapHasNumberKey() {
548
+ const mapKey = 123;
549
+ const oldDefaultMap = new DefaultMap<number, number>(456);
550
+ oldDefaultMap.getAndSetDefault(mapKey);
551
+
552
+ const serializedOldDefaultMap = deepCopy(
553
+ oldDefaultMap,
554
+ SerializationType.SERIALIZE,
555
+ "copiedSerializedDefaultMapHasNumberKey-serialize",
556
+ );
557
+
558
+ const newTable = deepCopy(
559
+ serializedOldDefaultMap,
560
+ SerializationType.DESERIALIZE,
561
+ "copiedSerializedDefaultMapHasNumberKey-deserialize",
562
+ );
563
+
564
+ const newDefaultMap = newTable as DefaultMap<number, number>;
565
+ if (!newDefaultMap.has(mapKey)) {
566
+ const keyType = type(mapKey);
567
+ error(
568
+ `The copied DefaultMap did not have a key of: ${mapKey} with type ${keyType}`,
569
+ );
570
+ }
571
+ }
@@ -1,12 +1,12 @@
1
- import * as json from "json";
1
+ import * as jsonLua from "../lib/jsonLua";
2
2
  import { logError } from "./log";
3
3
 
4
4
  function tryDecode(this: void, jsonString: string) {
5
- return json.decode(jsonString) as LuaMap;
5
+ return jsonLua.decode(jsonString) as LuaMap;
6
6
  }
7
7
 
8
8
  function tryEncode(this: void, luaTable: unknown) {
9
- return json.encode(luaTable);
9
+ return jsonLua.encode(luaTable);
10
10
  }
11
11
 
12
12
  /**
@@ -16,6 +16,9 @@ function tryEncode(this: void, luaTable: unknown) {
16
16
  * fails, it will return a blank Lua table instead of throwing an error. (This allows execution to
17
17
  * continue in cases where users have no current save data or have manually removed their existing
18
18
  * save data.)
19
+ *
20
+ * Under the hood, this uses a custom JSON parser that was measured to be 11.8 times faster than the
21
+ * vanilla JSON parser.
19
22
  */
20
23
  export function jsonDecode(jsonString: string): LuaMap<AnyNotNil, unknown> {
21
24
  const [ok, luaTableOrErrMsg] = pcall(tryDecode, jsonString);
@@ -34,6 +37,9 @@ export function jsonDecode(jsonString: string): LuaMap<AnyNotNil, unknown> {
34
37
  * In most cases, this function will be used for writing data to a "save#.dat" file. If encoding
35
38
  * fails, it will throw an error to prevent writing a blank string or corrupted data to a user's
36
39
  * "save#.dat" file.
40
+ *
41
+ * Under the hood, this uses a custom JSON parser that was measured to be 11.8 times faster than the
42
+ * vanilla JSON parser.
37
43
  */
38
44
  export function jsonEncode(luaTable: unknown): string {
39
45
  const [ok, jsonStringOrErrMsg] = pcall(tryEncode, luaTable);
@@ -640,6 +640,7 @@ export function logTable(
640
640
  return;
641
641
  }
642
642
 
643
+ let numElements = 0;
643
644
  iterateTableInOrder(luaTable, (key, value) => {
644
645
  // eslint-disable-next-line @typescript-eslint/no-base-to-string
645
646
  log(`${indentation}${key} --> ${value}`);
@@ -653,13 +654,14 @@ export function logTable(
653
654
  logTable(value, parentTables + 1);
654
655
  }
655
656
  }
657
+
658
+ numElements++;
656
659
  });
657
660
 
658
661
  // Put it in an IIFE so that the it will show as "func" instead of "logTable" and align with the
659
662
  // other text.
660
663
  (() => {
661
- const { length } = Object.keys(luaTable);
662
- log(`${indentation}The size of the table was: ${length}`);
664
+ log(`${indentation}The size of the table was: ${numElements}`);
663
665
  })();
664
666
  }
665
667
 
@@ -266,8 +266,6 @@ function oldTableHasFilledDefaultMap() {
266
266
  }
267
267
 
268
268
  function oldTableHasVector() {
269
- log("Starting test: oldTableHasVector");
270
-
271
269
  interface Foo {
272
270
  bar: Vector;
273
271
  }
@@ -307,8 +305,6 @@ function oldTableHasVector() {
307
305
  }
308
306
 
309
307
  function oldTableHasVectorSerialized() {
310
- log("Starting test: oldTableHasVectorSerialized");
311
-
312
308
  interface Foo {
313
309
  bar: Vector;
314
310
  }
@@ -355,8 +351,6 @@ function oldTableHasVectorSerialized() {
355
351
  }
356
352
 
357
353
  function oldTableHasRNG() {
358
- log("Starting test: oldTableHasRNG");
359
-
360
354
  interface Foo {
361
355
  bar: RNG;
362
356
  }
@@ -392,8 +386,6 @@ function oldTableHasRNG() {
392
386
  }
393
387
 
394
388
  function oldTableHasRNGSerialized() {
395
- log("Starting test: oldTableHasRNGSerialized");
396
-
397
389
  interface Foo {
398
390
  bar: RNG;
399
391
  }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * This is the custom JSON parser library called "json.lua". It is located at:
3
+ * https://github.com/rxi/json.lua
4
+ *
5
+ * This parser was measured to be 11.8 times faster than the vanilla parser at decoding a sample
6
+ * "save1.dat" file.
7
+ */
8
+
9
+ export function encode(this: void, data: unknown): string;
10
+ export function decode(this: void, data: string): unknown;