resurrect-esm 2.0.4 → 2.0.5

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
@@ -81,8 +81,8 @@ properties:
81
81
 
82
82
  * *resolver* (`NamespaceResolver`): Converts between a name
83
83
  and a prototype. Create a custom resolver if your constructors
84
- are not stored in global variables. The resolver has two methods:
85
- getName(object) and getPrototype(string).
84
+ are not stored in global variables. The resolver has three methods:
85
+ getName(object), getConstructor(string), and getPrototype(string).
86
86
 
87
87
  > [!CAUTION]
88
88
  > If you're using ES6 modules for your custom classes, you MUST use a custom resolver since module scope is not global scope!
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "resurrect-esm",
3
- "version": "2.0.4",
3
+ "version": "2.0.5",
4
4
  "type": "module",
5
5
  "description": "ResurrectJS preserves object behavior (prototypes) and reference circularity with a special JSON encoding. Unlike flat JSON, it can also properly resurrect self-referential objects, objects with shared structure, Dates, RegExps, HTMLElements, NaN, Infinity, undefined (which won't get turned into null), and any other custom object type given the proper resolver.",
6
6
  "repository": {
@@ -38,5 +38,8 @@
38
38
  "test": "pnpm bun test",
39
39
  "test:watch": "pnpm test --watch",
40
40
  "prepare": "pnpm build --minify --mangle-props=^_"
41
+ },
42
+ "dependencies": {
43
+ "lib0": "^0.2.117"
41
44
  }
42
45
  }
package/resurrect.test.ts CHANGED
@@ -98,6 +98,16 @@ function suite(opt?: ResurrectOptions) {
98
98
  expect(roundtripped).toBeInstanceOf(Dog);
99
99
  expect(roundtripped.woof()).toEqual("wowwowwow!");
100
100
  });
101
+ test("revive/serialize works with minifier-renamed classes", () => {
102
+ class z {
103
+ constructor(public foo: number) { };
104
+ }
105
+ const obj = new z(1);
106
+ const roundtripped = roundtrip(obj, {
107
+ resolver: new NamespaceResolver({ Foo: z }),
108
+ });
109
+ expect(roundtripped).toBeInstanceOf(z);
110
+ })
101
111
  test("can't serialize anonymous classes", () => {
102
112
  const obj = new class {
103
113
  foo: number;
package/resurrect.ts CHANGED
@@ -49,7 +49,8 @@
49
49
  * resolver (Resurrect.NamespaceResolver(window)): Converts between
50
50
  * a name and a prototype. Create a custom resolver if your
51
51
  * constructors are not stored in global variables. The resolver
52
- * has two methods: getName(object) and getPrototype(string).
52
+ * has three methods: getName(object), getConstructor(string), and
53
+ * getPrototype(string).
53
54
  *
54
55
  * For example,
55
56
  *
@@ -74,6 +75,11 @@
74
75
  * @see http://nullprogram.com/blog/2013/03/28/
75
76
  */
76
77
 
78
+ import { parse, stringify } from "lib0/json";
79
+ import { keys } from "lib0/object";
80
+
81
+ const getPrototypeOf = Object.getPrototypeOf;
82
+
77
83
  export class Resurrect {
78
84
  private _table: any[] | null;
79
85
  private _cleanups: (() => void)[] = [];
@@ -175,7 +181,7 @@ export class Resurrect {
175
181
  if (this.revive) {
176
182
  const constructor = this.resolver.getName(object);
177
183
  if (constructor) {
178
- const proto = Object.getPrototypeOf(object);
184
+ const proto = getPrototypeOf(object);
179
185
  if (this.resolver.getPrototype(constructor) !== proto) {
180
186
  throw new ResurrectError("Constructor mismatch!");
181
187
  } else {
@@ -256,7 +262,7 @@ export class Resurrect {
256
262
  copy.push(this._visit(root[i], transform, replacer));
257
263
  }
258
264
  } else { /* Object */
259
- copy = Object.create(Object.getPrototypeOf(root));
265
+ copy = Object.create(getPrototypeOf(root));
260
266
  root[this._refcode as any] = this._tag(copy);
261
267
  this._cleanups.push(() => delete root[this._refcode]);
262
268
  for (const key of Object.getOwnPropertyNames(root)) {
@@ -326,7 +332,7 @@ export class Resurrect {
326
332
  replacer = (k, v) => acceptKeys.includes(k) ? v : undefined;
327
333
  }
328
334
  if (Resurrect._isAtom(object)) {
329
- return JSON.stringify(this._handleAtom(object), replacer, space);
335
+ return stringify(this._handleAtom(object), replacer, space);
330
336
  } else {
331
337
  this._cleanups = [];
332
338
  const table = this._table = [] as any[];
@@ -348,7 +354,7 @@ export class Resurrect {
348
354
  }
349
355
  this._table = null;
350
356
  }
351
- const s = JSON.stringify(table, null, space);
357
+ const s = stringify(table, null, space);
352
358
  if (this.cleanup) this._cleanup();
353
359
  return s;
354
360
  }
@@ -386,7 +392,7 @@ export class Resurrect {
386
392
  */
387
393
  resurrect(string: string): any {
388
394
  let result = null;
389
- const data = JSON.parse(string);
395
+ const data = parse(string);
390
396
  try {
391
397
  if (Resurrect._isArray(data)) {
392
398
  this._table = data;
@@ -483,9 +489,10 @@ export class NamespaceResolver {
483
489
  * @returns null if the constructor is `Object` or `Array`.
484
490
  */
485
491
  getName(object: object): string | null {
486
- let constructor = object.constructor.name;
492
+ const constructorFun = object.constructor;
493
+ let constructor = keys(this.scope).find(realName => this.scope[realName] === constructorFun) ?? constructorFun.name;
487
494
  if (constructor == null) { // IE
488
- constructor = /^\s*function\s*([A-Za-z0-9_$]*)/.exec("" + object.constructor)?.[1] ?? "";
495
+ constructor = /^\s*function\s*([A-Za-z0-9_$]*)/.exec("" + constructorFun)?.[1] ?? "";
489
496
  }
490
497
  if (constructor === "") {
491
498
  throw new ResurrectError("Can't serialize objects with anonymous constructors.");