xref: /aosp_15_r20/external/perfetto/ui/src/base/static_initializers.ts (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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