"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PendingRef = exports.DeserializeContext = exports.SerializeContext = void 0;
var SerializeContext;
(function (SerializeContext) {
function create() {
const ids = new WeakMap();
let nextId = 0;
return {
getId: (obj) => ids.get(obj),
register: (obj) => {
const id = nextId++;
ids.set(obj, id);
return id;
},
};
}
SerializeContext.create = create;
})(SerializeContext || (exports.SerializeContext = SerializeContext = {}));
var DeserializeContext;
(function (DeserializeContext) {
function create() {
const registry = new Map();
const patches = [];
const toFreeze = [];
return {
register: (id, instance) => {
registry.set(id, instance);
},
getOrDefer: (refId) => {
if (registry.has(refId)) {
return registry.get(refId);
}
return PendingRef.create(refId);
},
assignOrDefer: (target, prop, value) => {
if (PendingRef.is(value)) {
target[prop] = null;
patches.push({ target, prop, refId: value.id });
}
else {
target[prop] = value;
}
},
addPatch: (target, prop, refId) => {
patches.push({ target, prop, refId });
},
trackForFreeze: (obj) => {
toFreeze.push(obj);
},
applyPatches: () => {
for (const { target, prop, refId } of patches) {
if (!registry.has(refId)) {
throw new Error(`Unresolved reference: __ref ${refId}`);
}
target[prop] = registry.get(refId);
}
},
freezeAll: () => {
for (const obj of toFreeze) {
Object.freeze(obj);
}
},
};
}
DeserializeContext.create = create;
})(DeserializeContext || (exports.DeserializeContext = DeserializeContext = {}));
var PendingRef;
(function (PendingRef) {
function create(id) {
return { __pendingRef: true, id };
}
PendingRef.create = create;
function is(value) {
return (value !== null &&
typeof value === "object" &&
value.__pendingRef === true &&
typeof value.id === "number");
}
PendingRef.is = is;
})(PendingRef || (exports.PendingRef = PendingRef = {}));