@atlaskit/react-compiler-gating 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @atlaskit/react-compiler-gating
2
2
 
3
+ ## 0.2.5
4
+
5
+ ### Patch Changes
6
+
7
+ - [`18a1c474f8fd9`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/18a1c474f8fd9) -
8
+ Behind the `confluence_cache_react_compiler_fg` experiment, `isReactCompilerActivePlatform` caches
9
+ its result for the page load once Statsig has initialised. It never caches before initialisation,
10
+ when the experiment returns its default. The React Compiler calls this function once per compiled
11
+ function when its module first runs, often during hydration.
12
+
3
13
  ## 0.2.4
4
14
 
5
15
  ### Patch Changes
@@ -6,14 +6,35 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.isReactCompilerActivePlatform = isReactCompilerActivePlatform;
8
8
  var _featureGates = _interopRequireDefault(require("@atlaskit/feature-gate-js-client/feature-gates"));
9
+ // The React Compiler calls this once per compiled function, when its module first runs.
10
+ var cachedIsActive;
11
+ var shouldCacheIsActive;
12
+
13
+ // expVal from @atlaskit/platform-feature-experiments would import @atlaskit/react-ufo, which is
14
+ // itself compiled with this gating function.
15
+ function isExperimentEnabled(experimentName) {
16
+ return Boolean(_featureGates.default.getExperimentValue(experimentName, 'isEnabled', false));
17
+ }
18
+
9
19
  /**
10
20
  * Returns true if the React Compiler runtime is active for platform packages.
11
21
  *
12
22
  * Controlled by the 'confluence_enable_react-compiler-runtime-platform' experiment in Switcheroo.
23
+ * Behind the 'confluence_cache_react_compiler_fg' experiment, the result is cached for the page
24
+ * load once Statsig has initialised.
13
25
  */
14
26
  function isReactCompilerActivePlatform() {
15
- if (_featureGates.default.getExperimentValue('confluence_enable_react-compiler-runtime-platform', 'isEnabled', false)) {
16
- return true;
27
+ if (cachedIsActive !== undefined) {
28
+ return cachedIsActive;
29
+ }
30
+ var isActive = isExperimentEnabled('confluence_enable_react-compiler-runtime-platform');
31
+
32
+ // Before Statsig initialises, getExperimentValue returns the default, which must not be cached.
33
+ if (shouldCacheIsActive === undefined && _featureGates.default.initializeCompleted()) {
34
+ shouldCacheIsActive = isExperimentEnabled('confluence_cache_react_compiler_fg');
35
+ }
36
+ if (shouldCacheIsActive) {
37
+ cachedIsActive = isActive;
17
38
  }
18
- return false;
39
+ return isActive;
19
40
  }
@@ -1,13 +1,34 @@
1
1
  import FeatureGates from '@atlaskit/feature-gate-js-client/feature-gates';
2
2
 
3
+ // The React Compiler calls this once per compiled function, when its module first runs.
4
+ let cachedIsActive;
5
+ let shouldCacheIsActive;
6
+
7
+ // expVal from @atlaskit/platform-feature-experiments would import @atlaskit/react-ufo, which is
8
+ // itself compiled with this gating function.
9
+ function isExperimentEnabled(experimentName) {
10
+ return Boolean(FeatureGates.getExperimentValue(experimentName, 'isEnabled', false));
11
+ }
12
+
3
13
  /**
4
14
  * Returns true if the React Compiler runtime is active for platform packages.
5
15
  *
6
16
  * Controlled by the 'confluence_enable_react-compiler-runtime-platform' experiment in Switcheroo.
17
+ * Behind the 'confluence_cache_react_compiler_fg' experiment, the result is cached for the page
18
+ * load once Statsig has initialised.
7
19
  */
8
20
  export function isReactCompilerActivePlatform() {
9
- if (FeatureGates.getExperimentValue('confluence_enable_react-compiler-runtime-platform', 'isEnabled', false)) {
10
- return true;
21
+ if (cachedIsActive !== undefined) {
22
+ return cachedIsActive;
23
+ }
24
+ const isActive = isExperimentEnabled('confluence_enable_react-compiler-runtime-platform');
25
+
26
+ // Before Statsig initialises, getExperimentValue returns the default, which must not be cached.
27
+ if (shouldCacheIsActive === undefined && FeatureGates.initializeCompleted()) {
28
+ shouldCacheIsActive = isExperimentEnabled('confluence_cache_react_compiler_fg');
29
+ }
30
+ if (shouldCacheIsActive) {
31
+ cachedIsActive = isActive;
11
32
  }
12
- return false;
33
+ return isActive;
13
34
  }
@@ -1,13 +1,34 @@
1
1
  import FeatureGates from '@atlaskit/feature-gate-js-client/feature-gates';
2
2
 
3
+ // The React Compiler calls this once per compiled function, when its module first runs.
4
+ var cachedIsActive;
5
+ var shouldCacheIsActive;
6
+
7
+ // expVal from @atlaskit/platform-feature-experiments would import @atlaskit/react-ufo, which is
8
+ // itself compiled with this gating function.
9
+ function isExperimentEnabled(experimentName) {
10
+ return Boolean(FeatureGates.getExperimentValue(experimentName, 'isEnabled', false));
11
+ }
12
+
3
13
  /**
4
14
  * Returns true if the React Compiler runtime is active for platform packages.
5
15
  *
6
16
  * Controlled by the 'confluence_enable_react-compiler-runtime-platform' experiment in Switcheroo.
17
+ * Behind the 'confluence_cache_react_compiler_fg' experiment, the result is cached for the page
18
+ * load once Statsig has initialised.
7
19
  */
8
20
  export function isReactCompilerActivePlatform() {
9
- if (FeatureGates.getExperimentValue('confluence_enable_react-compiler-runtime-platform', 'isEnabled', false)) {
10
- return true;
21
+ if (cachedIsActive !== undefined) {
22
+ return cachedIsActive;
23
+ }
24
+ var isActive = isExperimentEnabled('confluence_enable_react-compiler-runtime-platform');
25
+
26
+ // Before Statsig initialises, getExperimentValue returns the default, which must not be cached.
27
+ if (shouldCacheIsActive === undefined && FeatureGates.initializeCompleted()) {
28
+ shouldCacheIsActive = isExperimentEnabled('confluence_cache_react_compiler_fg');
29
+ }
30
+ if (shouldCacheIsActive) {
31
+ cachedIsActive = isActive;
11
32
  }
12
- return false;
33
+ return isActive;
13
34
  }
@@ -2,5 +2,7 @@
2
2
  * Returns true if the React Compiler runtime is active for platform packages.
3
3
  *
4
4
  * Controlled by the 'confluence_enable_react-compiler-runtime-platform' experiment in Switcheroo.
5
+ * Behind the 'confluence_cache_react_compiler_fg' experiment, the result is cached for the page
6
+ * load once Statsig has initialised.
5
7
  */
6
8
  export declare function isReactCompilerActivePlatform(): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/react-compiler-gating",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "Runtime gating for enabling the React Compiler in Atlassian platform packages.",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -0,0 +1,129 @@
1
+ import FeatureGates from '@atlaskit/feature-gate-js-client/feature-gates';
2
+
3
+ const COMPILER_EXPERIMENT = 'confluence_enable_react-compiler-runtime-platform';
4
+ const CACHE_EXPERIMENT = 'confluence_cache_react_compiler_fg';
5
+
6
+ // The gating module keeps its cache at module scope, so every test loads a fresh copy.
7
+ const loadIsReactCompilerActivePlatform = (): (() => boolean) => {
8
+ let isReactCompilerActivePlatform: (() => boolean) | undefined;
9
+ jest.isolateModules(() => {
10
+ isReactCompilerActivePlatform =
11
+ require('../isReactCompilerActivePlatform').isReactCompilerActivePlatform;
12
+ });
13
+ return isReactCompilerActivePlatform!;
14
+ };
15
+
16
+ describe('isReactCompilerActivePlatform', () => {
17
+ let experimentValues: Record<string, unknown>;
18
+ let getExperimentValueSpy: jest.SpyInstance;
19
+ let initializeCompletedSpy: jest.SpyInstance;
20
+
21
+ const setExperimentValue = (experimentName: string, value: unknown) => {
22
+ experimentValues[experimentName] = value;
23
+ };
24
+ const setInitializeCompleted = (value: boolean) => initializeCompletedSpy.mockReturnValue(value);
25
+ const experimentReads = (experimentName: string) =>
26
+ getExperimentValueSpy.mock.calls.filter(([name]) => name === experimentName).length;
27
+
28
+ beforeEach(() => {
29
+ experimentValues = {};
30
+ getExperimentValueSpy = jest
31
+ .spyOn(FeatureGates, 'getExperimentValue')
32
+ .mockImplementation(
33
+ (experimentName, _param, defaultValue) =>
34
+ (experimentValues[experimentName] ?? defaultValue) as never,
35
+ );
36
+ initializeCompletedSpy = jest.spyOn(FeatureGates, 'initializeCompleted').mockReturnValue(false);
37
+ });
38
+
39
+ afterEach(() => {
40
+ getExperimentValueSpy.mockRestore();
41
+ initializeCompletedSpy.mockRestore();
42
+ });
43
+
44
+ it('reads the experiment on every call before Statsig initialises', () => {
45
+ const isReactCompilerActivePlatform = loadIsReactCompilerActivePlatform();
46
+ setExperimentValue(CACHE_EXPERIMENT, true);
47
+ setExperimentValue(COMPILER_EXPERIMENT, true);
48
+
49
+ expect(isReactCompilerActivePlatform()).toBe(true);
50
+ expect(isReactCompilerActivePlatform()).toBe(true);
51
+
52
+ expect(experimentReads(COMPILER_EXPERIMENT)).toBe(2);
53
+ expect(experimentReads(CACHE_EXPERIMENT)).toBe(0);
54
+ });
55
+
56
+ it('does not cache the default returned before Statsig initialises', () => {
57
+ const isReactCompilerActivePlatform = loadIsReactCompilerActivePlatform();
58
+ setExperimentValue(CACHE_EXPERIMENT, true);
59
+
60
+ expect(isReactCompilerActivePlatform()).toBe(false);
61
+
62
+ setInitializeCompleted(true);
63
+ setExperimentValue(COMPILER_EXPERIMENT, true);
64
+
65
+ expect(isReactCompilerActivePlatform()).toBe(true);
66
+ });
67
+
68
+ it('caches the result after Statsig initialises when the cache experiment is on', () => {
69
+ const isReactCompilerActivePlatform = loadIsReactCompilerActivePlatform();
70
+ setExperimentValue(CACHE_EXPERIMENT, true);
71
+ setInitializeCompleted(true);
72
+ setExperimentValue(COMPILER_EXPERIMENT, true);
73
+
74
+ expect(isReactCompilerActivePlatform()).toBe(true);
75
+ setExperimentValue(COMPILER_EXPERIMENT, false);
76
+ expect(isReactCompilerActivePlatform()).toBe(true);
77
+ expect(isReactCompilerActivePlatform()).toBe(true);
78
+
79
+ expect(experimentReads(COMPILER_EXPERIMENT)).toBe(1);
80
+ });
81
+
82
+ it('caches a false result', () => {
83
+ const isReactCompilerActivePlatform = loadIsReactCompilerActivePlatform();
84
+ setExperimentValue(CACHE_EXPERIMENT, true);
85
+ setInitializeCompleted(true);
86
+
87
+ expect(isReactCompilerActivePlatform()).toBe(false);
88
+ setExperimentValue(COMPILER_EXPERIMENT, true);
89
+ expect(isReactCompilerActivePlatform()).toBe(false);
90
+
91
+ expect(experimentReads(COMPILER_EXPERIMENT)).toBe(1);
92
+ });
93
+
94
+ it('reads the experiment on every call when the cache experiment is off', () => {
95
+ const isReactCompilerActivePlatform = loadIsReactCompilerActivePlatform();
96
+ setExperimentValue(CACHE_EXPERIMENT, false);
97
+ setInitializeCompleted(true);
98
+ setExperimentValue(COMPILER_EXPERIMENT, true);
99
+
100
+ expect(isReactCompilerActivePlatform()).toBe(true);
101
+ expect(isReactCompilerActivePlatform()).toBe(true);
102
+ setExperimentValue(COMPILER_EXPERIMENT, false);
103
+ expect(isReactCompilerActivePlatform()).toBe(false);
104
+
105
+ expect(experimentReads(COMPILER_EXPERIMENT)).toBe(3);
106
+ });
107
+
108
+ it('reads the cache experiment once, after Statsig initialises', () => {
109
+ const isReactCompilerActivePlatform = loadIsReactCompilerActivePlatform();
110
+ setExperimentValue(CACHE_EXPERIMENT, false);
111
+
112
+ isReactCompilerActivePlatform();
113
+ expect(experimentReads(CACHE_EXPERIMENT)).toBe(0);
114
+
115
+ setInitializeCompleted(true);
116
+ isReactCompilerActivePlatform();
117
+ isReactCompilerActivePlatform();
118
+ isReactCompilerActivePlatform();
119
+
120
+ expect(experimentReads(CACHE_EXPERIMENT)).toBe(1);
121
+ });
122
+
123
+ it('returns false for a value that is not truthy', () => {
124
+ const isReactCompilerActivePlatform = loadIsReactCompilerActivePlatform();
125
+ setExperimentValue(COMPILER_EXPERIMENT, 0);
126
+
127
+ expect(isReactCompilerActivePlatform()).toBe(false);
128
+ });
129
+ });
@@ -1,19 +1,37 @@
1
1
  import FeatureGates from '@atlaskit/feature-gate-js-client/feature-gates';
2
2
 
3
+ // The React Compiler calls this once per compiled function, when its module first runs.
4
+ let cachedIsActive: boolean | undefined;
5
+ let shouldCacheIsActive: boolean | undefined;
6
+
7
+ // expVal from @atlaskit/platform-feature-experiments would import @atlaskit/react-ufo, which is
8
+ // itself compiled with this gating function.
9
+ function isExperimentEnabled(experimentName: string): boolean {
10
+ return Boolean(FeatureGates.getExperimentValue(experimentName, 'isEnabled', false));
11
+ }
12
+
3
13
  /**
4
14
  * Returns true if the React Compiler runtime is active for platform packages.
5
15
  *
6
16
  * Controlled by the 'confluence_enable_react-compiler-runtime-platform' experiment in Switcheroo.
17
+ * Behind the 'confluence_cache_react_compiler_fg' experiment, the result is cached for the page
18
+ * load once Statsig has initialised.
7
19
  */
8
20
  export function isReactCompilerActivePlatform(): boolean {
9
- if (
10
- FeatureGates.getExperimentValue(
11
- 'confluence_enable_react-compiler-runtime-platform',
12
- 'isEnabled',
13
- false,
14
- )
15
- ) {
16
- return true;
21
+ if (cachedIsActive !== undefined) {
22
+ return cachedIsActive;
17
23
  }
18
- return false;
24
+
25
+ const isActive = isExperimentEnabled('confluence_enable_react-compiler-runtime-platform');
26
+
27
+ // Before Statsig initialises, getExperimentValue returns the default, which must not be cached.
28
+ if (shouldCacheIsActive === undefined && FeatureGates.initializeCompleted()) {
29
+ shouldCacheIsActive = isExperimentEnabled('confluence_cache_react_compiler_fg');
30
+ }
31
+
32
+ if (shouldCacheIsActive) {
33
+ cachedIsActive = isActive;
34
+ }
35
+
36
+ return isActive;
19
37
  }
package/tsconfig.app.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "extends": "../../../tsconfig.base.json",
3
- "include": ["./src/**/*.ts", "./src/**/*.tsx"],
4
- "exclude": [
3
+ "include": [
4
+ "./src/**/*.ts",
5
+ "./src/**/*.tsx",
5
6
  "**/docs/**/*",
6
7
  "**/__tests__/**/*",
7
8
  "**/vr-tests/**/*",
@@ -29,6 +30,7 @@
29
30
  "**/codemods/**/*.ts",
30
31
  "**/codemods/**/*.tsx"
31
32
  ],
33
+ "exclude": [],
32
34
  "compilerOptions": {
33
35
  "composite": true,
34
36
  "outDir": "../../../tsDist/@atlaskit__react-compiler-gating/app",
package/tsconfig.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "extends": "./tsconfig.dev.json",
2
+ "extends": "./tsconfig.app.json",
3
3
  "compilerOptions": {
4
4
  "disableReferencedProjectLoad": true,
5
5
  "disableSolutionSearching": true
package/tsconfig.dev.json DELETED
@@ -1,42 +0,0 @@
1
- {
2
- "extends": "../../../tsconfig.base.json",
3
- "include": [
4
- "**/docs/**/*",
5
- "**/__tests__/**/*",
6
- "**/vr-tests/**/*",
7
- "**/__perf__/**/*",
8
- "**/*.test.*",
9
- "**/test.*",
10
- "**/test-*",
11
- "**/examples.ts",
12
- "**/examples.tsx",
13
- "**/examples/*.ts",
14
- "**/examples/*.tsx",
15
- "**/examples/**/*.ts",
16
- "**/examples/**/*.tsx",
17
- "**/storybook/**/*",
18
- "**/constellation/**/*",
19
- "../src/**/*.stories.*",
20
- "../src/**/stories/*",
21
- "../src/**/stories/**/*",
22
- ".storybook/*",
23
- "./__fixtures__/**/*",
24
- "./__generated__/**/*",
25
- "./mocks/**/*",
26
- "./__mocks__/**/*",
27
- "**/mock.*",
28
- "**/codemods/**/*.ts",
29
- "**/codemods/**/*.tsx"
30
- ],
31
- "exclude": ["./dist/**/*", "./build/**/*", "./node_modules/**/*"],
32
- "compilerOptions": {
33
- "composite": true,
34
- "outDir": "../../../tsDist/@atlaskit__react-compiler-gating/dev",
35
- "isolatedDeclarations": true
36
- },
37
- "references": [
38
- {
39
- "path": "./tsconfig.app.json"
40
- }
41
- ]
42
- }