* Restores this instance from the provided deserializer context. * @param {SerializedType} data data * @param {Context} context context object * @returns {DeserializedType | Promise<DeserializedType>} deserialized data
(data, context)
| 738 | * @returns {DeserializedType | Promise<DeserializedType>} deserialized data |
| 739 | */ |
| 740 | deserialize(data, context) { |
| 741 | let currentDataPos = 0; |
| 742 | const read = () => { |
| 743 | if (currentDataPos >= data.length) { |
| 744 | throw new Error("Unexpected end of stream"); |
| 745 | } |
| 746 | |
| 747 | return data[currentDataPos++]; |
| 748 | }; |
| 749 | |
| 750 | if (read() !== CURRENT_VERSION) { |
| 751 | throw new Error("Version mismatch, serializer changed"); |
| 752 | } |
| 753 | |
| 754 | let currentPos = 0; |
| 755 | /** @type {ReferenceableItem[]} */ |
| 756 | let referenceable = []; |
| 757 | /** |
| 758 | * Adds referenceable. |
| 759 | * @param {ReferenceableItem} item referenceable item |
| 760 | */ |
| 761 | const addReferenceable = (item) => { |
| 762 | referenceable.push(item); |
| 763 | currentPos++; |
| 764 | }; |
| 765 | let currentPosTypeLookup = 0; |
| 766 | /** @type {ObjectSerializer[]} */ |
| 767 | let objectTypeLookup = []; |
| 768 | /** @type {ComplexSerializableType[]} */ |
| 769 | let result = []; |
| 770 | /** @type {ObjectDeserializerContext<EXPECTED_ANY>} */ |
| 771 | let ctx = { |
| 772 | read() { |
| 773 | return /** @type {EXPECTED_ANY} */ (decodeValue()); |
| 774 | }, |
| 775 | // type-only cursor advance; same object, retyped to the tuple tail |
| 776 | get rest() { |
| 777 | return ctx; |
| 778 | }, |
| 779 | setCircularReference(ref) { |
| 780 | addReferenceable(ref); |
| 781 | }, |
| 782 | ...context |
| 783 | }; |
| 784 | this.extendContext(ctx); |
| 785 | /** |
| 786 | * Decodes the provided value. |
| 787 | * @returns {ComplexSerializableType} deserialize value |
| 788 | */ |
| 789 | const decodeValue = () => { |
| 790 | const item = read(); |
| 791 | |
| 792 | if (item === ESCAPE) { |
| 793 | const nextItem = read(); |
| 794 | |
| 795 | if (nextItem === ESCAPE_ESCAPE_VALUE) { |
| 796 | return ESCAPE; |
| 797 | } else if (nextItem === ESCAPE_UNDEFINED) { |
no test coverage detected