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.
- package/dist/functions/deepCopy.lua +50 -14
- package/dist/functions/deepCopyTests.d.ts.map +1 -1
- package/dist/functions/deepCopyTests.lua +78 -21
- package/dist/functions/jsonHelpers.d.ts +6 -0
- package/dist/functions/jsonHelpers.d.ts.map +1 -1
- package/dist/functions/jsonHelpers.lua +9 -3
- package/dist/functions/log.d.ts.map +1 -1
- package/dist/functions/log.lua +3 -3
- package/dist/functions/mergeTests.lua +0 -4
- package/dist/lib/jsonLua.lua +388 -0
- package/package.json +1 -1
- package/src/functions/deepCopy.ts +56 -5
- package/src/functions/deepCopyTests.ts +146 -17
- package/src/functions/jsonHelpers.ts +9 -3
- package/src/functions/log.ts +4 -2
- package/src/functions/mergeTests.ts +0 -8
- package/src/lib/jsonLua.d.ts +10 -0
- package/src/lib/jsonLua.lua +388 -0
|
@@ -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(
|
|
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(
|
|
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 = "
|
|
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(
|
|
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(
|
|
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
|
|
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
|
|
5
|
+
return jsonLua.decode(jsonString) as LuaMap;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
function tryEncode(this: void, luaTable: unknown) {
|
|
9
|
-
return
|
|
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);
|
package/src/functions/log.ts
CHANGED
|
@@ -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
|
-
|
|
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;
|