{"version":3,"file":"Encoder.js","sourceRoot":"","sources":["../src/Encoder.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Schema } from \"./Schema\";\nimport { TypeContext } from \"./annotations\";\nimport { $changes, $encoder } from \"./changes/consts\";\n\nimport * as encode from \"./encoding/encode\";\nimport { SWITCH_TO_STRUCTURE, TYPE_ID, OPERATION } from './spec';\nimport { ChangeOperation, ChangeTracker, Root } from \"./changes/ChangeTree\";\nimport { encodeKeyValueOperation, encodeSchemaOperation } from \"./changes/EncodeOperation\";\n\nexport class Encoder<T extends Schema = any> {\n    context: TypeContext;\n\n    root: T;\n    $root: Root;\n\n    constructor(root: T) {\n        this.setRoot(root);\n\n        //\n        // TODO: cache and restore \"Context\" based on root schema\n        // (to avoid creating a new context for each new room)\n        //\n        this.context = new TypeContext(root.constructor as typeof Schema);\n\n        // console.log(\">>>>>>>>>>>>>>>> Encoder types\");\n        // this.context.schemas.forEach((id, schema) => {\n        //     console.log(\"type:\", id, schema.name, Object.keys(schema[Symbol.metadata]));\n        // });\n    }\n\n    protected setRoot(root: T) {\n        this.$root = new Root();\n        this.root = root;\n        root[$changes].setRoot(this.$root);\n    }\n\n    encode(\n        encodeAll = false,\n        bytes: number[] = [],\n        useFilters: boolean = false,\n    ) {\n        const rootChangeTree = this.root[$changes];\n\n        // const changeTrees: ChangeTracker[] = Array.from(this.$root['currentQueue']);\n        const changeTrees: ChangeTracker[] = this.$root.changes;\n        const numChangeTrees = changeTrees.length;\n        // let numChangeTrees = 1;\n\n        // console.log(\"--------------------- ENCODE ----------------\");\n        // console.log(\"Encode order:\", changeTrees.map((c) => c.ref['constructor'].name));\n        for (let i = 0; i < numChangeTrees; i++) {\n            const changeTree = changeTrees[i];\n            const ref = changeTree.ref;\n\n            // Generate unique refId for the ChangeTree.\n            changeTree.ensureRefId();\n\n            // root `refId` is skipped.\n            if (\n                changeTree !== rootChangeTree &&\n                (changeTree.changed || encodeAll)\n            ) {\n                encode.uint8(bytes, SWITCH_TO_STRUCTURE);\n                encode.number(bytes, changeTree.refId);\n            }\n\n            const changes: IterableIterator<ChangeOperation | number> = (encodeAll)\n                ? changeTree.allChanges.values()\n                : changeTree.changes.values();\n\n            let change: IteratorResult<ChangeOperation | number>;\n            while (!(change = changes.next()).done) {\n                const operation = (encodeAll)\n                    ? OPERATION.ADD\n                    : change.value.op;\n\n                const fieldIndex = (encodeAll)\n                    ? change.value\n                    : change.value.index;\n\n                const encoder = ref['constructor'][$encoder];\n                encoder(this, bytes, changeTree, fieldIndex, operation);\n            }\n\n            if (!encodeAll && !useFilters) {\n                changeTree.discard();\n            }\n        }\n\n        return bytes;\n    }\n\n    encodeAll (useFilters?: boolean) {\n        return this.encode(true, [], useFilters);\n    }\n\n    tryEncodeTypeId (bytes: number[], baseType: typeof Schema, targetType: typeof Schema) {\n        const baseTypeId = this.context.getTypeId(baseType);\n        const targetTypeId = this.context.getTypeId(targetType);\n\n        if (baseTypeId !== targetTypeId) {\n            encode.uint8(bytes, TYPE_ID);\n            encode.number(bytes, targetTypeId);\n        }\n    }\n\n}"]}