1// Copyright (C) 2023 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15// Occasionally libraries require configuration code to be called 16// before that library is used. This can become troublesome when the 17// library is used in many places through out the code base. To ensure 18// a consistent initialization this file exists as a place such code 19// can live. It's the first import in the root file of the bundle. 20 21// We use 'static initializers' (e.g. first import causes 22// initialization) rather than allowing the importer control over when 23// it happens. This sounds worse on paper but it works a lot better in 24// tests where (in JS) there is no global main() you can edit to do the 25// initialization. Instead any test where this is a problem can easily 26// stick an import at the top of the file. 27 28import {enableMapSet, enablePatches, setAutoFreeze} from 'immer'; 29import protobuf from 'protobufjs/minimal'; 30 31function initializeImmer() { 32 enablePatches(); 33 enableMapSet(); 34 35 // TODO(primiano): re-enable this, requires fixing some bugs that this bubbles 36 // up. This is a new feature of immer which freezes object after a produce(). 37 // Unfortunately we piled up a bunch of bugs where we shallow-copy objects 38 // from the global state (which is frozen) and later try to update the copies. 39 // By doing so, we accidentally the local copy of global state, which is 40 // supposed to be immutable. 41 setAutoFreeze(true); 42} 43 44function initializeProtobuf() { 45 // Disable Long.js support in protobuf. This seems to be enabled only in tests 46 // but not in production code. In any case, for now we want casting to number 47 // accepting the 2**53 limitation. This is consistent with passing 48 // --force-number in the protobuf.js codegen invocation in //ui/BUILD.gn . 49 // See also https://github.com/protobufjs/protobuf.js/issues/1253 . 50 // eslint-disable-next-line @typescript-eslint/no-explicit-any 51 protobuf.util.Long = undefined as any; 52 protobuf.configure(); 53} 54 55let isInitialized = false; 56function initialize() { 57 if (isInitialized) { 58 throw new Error('initialize() should be called exactly once'); 59 } 60 initializeImmer(); 61 initializeProtobuf(); 62 isInitialized = true; 63} 64 65// JS module semantics ensure this is happens only once. 66initialize(); 67