Skip to content

Commit d26a135

Browse files
committed
Fix flexbox web worker race condition
1 parent d642cce commit d26a135

File tree

6 files changed

+38
-28
lines changed

6 files changed

+38
-28
lines changed

.changeset/icy-toes-report.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@plextv/react-native-lightning-example": patch
3+
"@plextv/react-lightning-example": patch
4+
"@plextv/react-lightning-plugin-flexbox": patch
5+
---
6+
7+
Fix race condition in flexbox worker mode

apps/react-lightning-example/vite.config.mjs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,6 @@ const config = {
3939
},
4040
force: true,
4141
},
42-
define: {
43-
'process.env': JSON.stringify({
44-
NODE_ENV: process.env.NODE_ENV,
45-
}),
46-
},
4742
};
4843

4944
export default config;

apps/react-native-lightning-example/vite.config.mjs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import reactReanimatedLightningPlugin from '@plextv/vite-plugin-react-reanimated
44
import legacy from '@vitejs/plugin-legacy';
55
import { defineConfig } from 'vite';
66

7-
const config = defineConfig({
7+
const config = defineConfig((env) => ({
88
base: './',
99
plugins: [
1010
reactNativeLightningPlugin(),
@@ -30,11 +30,10 @@ const config = defineConfig({
3030
hmr: false,
3131
},
3232
define: {
33-
'process.env': JSON.stringify({
34-
NODE_ENV: process.env.NODE_ENV,
35-
}),
36-
__DEV__: JSON.stringify(process.env.NODE_ENV !== 'production'),
33+
__DEV__: JSON.stringify(
34+
(env.mode ?? process.env.NODE_ENV) !== 'production',
35+
),
3736
},
38-
});
37+
}));
3938

4039
export default config;

apps/storybook/.storybook/main.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ const config: StorybookConfig = {
1616
},
1717
viteFinal(config) {
1818
config.define = {
19-
'process.env': JSON.stringify({
20-
NODE_ENV: process.env.NODE_ENV,
21-
}),
22-
__DEV__: JSON.stringify(process.env.NODE_ENV !== 'production'),
19+
__DEV__: JSON.stringify(
20+
(config.mode ?? process.env.NODE_ENV) !== 'production',
21+
),
2322
};
2423

2524
config.plugins = [

packages/plugin-flexbox/src/YogaManagerWorker.ts

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { LightningElementStyle } from '@plextv/react-lightning';
22
import { EventEmitter } from 'tseep';
33
import { NodeOperations } from './types/NodeOperations';
44
import { SimpleDataView } from './util/SimpleDataView';
5-
import Worker from './worker?worker';
5+
import Worker from './worker?worker&inline';
66
import type { YogaManager, YogaManagerEvents } from './YogaManager';
77

88
const DELAY_DURATION = 1;
@@ -50,9 +50,16 @@ function wrapWorker<T>(worker: Worker): Workerized<T> {
5050
const _eventEmitter = new EventEmitter<YogaManagerEvents>();
5151
let _stylesToSend: Record<number, Partial<LightningElementStyle>> = {};
5252
let _needsRender = false;
53-
// TODO: Handle possible overflows
54-
const _childOperations = new SimpleDataView();
55-
const _sizeRequests = new SimpleDataView();
53+
const _childOperations = new SimpleDataView(
54+
undefined,
55+
undefined,
56+
flushChildOperations,
57+
);
58+
const _sizeRequests = new SimpleDataView(
59+
undefined,
60+
undefined,
61+
flushSizeRequests,
62+
);
5663
let _sizeRequestPromise: Promise<void> | null = null;
5764

5865
const queueSendStyles = delay(() => {
@@ -62,6 +69,10 @@ function wrapWorker<T>(worker: Worker): Workerized<T> {
6269
return;
6370
}
6471

72+
// If we need to send styles, make sure we send any pending
73+
// child operations first
74+
flushChildOperations();
75+
6576
worker.postMessage({
6677
method: 'applyStyles',
6778
args: [_stylesToSend, !needsRender],
@@ -90,7 +101,7 @@ function wrapWorker<T>(worker: Worker): Workerized<T> {
90101
queueSendStyles();
91102
}
92103

93-
const queueSendNodeOperations = delay(() => {
104+
function flushChildOperations() {
94105
const buffer = _childOperations.buffer;
95106

96107
if (buffer.byteLength === 0) {
@@ -106,7 +117,9 @@ function wrapWorker<T>(worker: Worker): Workerized<T> {
106117
}
107118

108119
_childOperations.reset();
109-
}, DELAY_DURATION);
120+
}
121+
122+
const queueSendNodeOperations = delay(flushChildOperations, DELAY_DURATION);
110123

111124
function nodeOperation(
112125
method: 'addNode' | 'removeNode' | 'addChildNode',
@@ -150,7 +163,7 @@ function wrapWorker<T>(worker: Worker): Workerized<T> {
150163
queueSendNodeOperations();
151164
}
152165

153-
const queueSendSizeRequests = delay(() => {
166+
function flushSizeRequests() {
154167
if (_sizeRequestPromise) {
155168
return _sizeRequestPromise;
156169
}
@@ -207,7 +220,9 @@ function wrapWorker<T>(worker: Worker): Workerized<T> {
207220

208221
_sizeRequests.reset();
209222
});
210-
}, DELAY_DURATION);
223+
}
224+
225+
const queueSendSizeRequests = delay(flushSizeRequests, DELAY_DURATION);
211226

212227
function getClampedSize(elementId: number) {
213228
const callbackId = getId();

templates/app-template/vite.config.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,6 @@ const config: InlineConfig = {
2222
build: {
2323
target: 'esnext',
2424
},
25-
define: {
26-
'process.env': JSON.stringify({
27-
NODE_ENV: process.env.NODE_ENV,
28-
}),
29-
},
3025
};
3126

3227
export default config;

0 commit comments

Comments
 (0)