@tamagui/web 3.0.3 → 3.0.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.
Files changed (36) hide show
  1. package/dist/cjs/_withNativeStyle.cjs +85 -46
  2. package/dist/cjs/_withNativeStyle.native.cjs +91 -41
  3. package/dist/cjs/_withNativeStyle.native.js +91 -41
  4. package/dist/cjs/_withNativeStyle.native.js.map +1 -1
  5. package/dist/cjs/helpers/nativeStyleEngine.cjs +140 -69
  6. package/dist/cjs/helpers/nativeStyleEngine.native.cjs +177 -118
  7. package/dist/cjs/helpers/nativeStyleEngine.native.js +177 -118
  8. package/dist/cjs/helpers/nativeStyleEngine.native.js.map +1 -1
  9. package/dist/cjs/index.cjs +1 -0
  10. package/dist/cjs/index.native.cjs +1 -0
  11. package/dist/cjs/index.native.js +1 -0
  12. package/dist/cjs/index.native.js.map +1 -1
  13. package/dist/esm/_withNativeStyle.mjs +85 -40
  14. package/dist/esm/_withNativeStyle.mjs.map +1 -1
  15. package/dist/esm/_withNativeStyle.native.js +92 -42
  16. package/dist/esm/_withNativeStyle.native.js.map +1 -1
  17. package/dist/esm/helpers/nativeStyleEngine.mjs +141 -71
  18. package/dist/esm/helpers/nativeStyleEngine.mjs.map +1 -1
  19. package/dist/esm/helpers/nativeStyleEngine.native.js +177 -119
  20. package/dist/esm/helpers/nativeStyleEngine.native.js.map +1 -1
  21. package/dist/esm/index.js +2 -2
  22. package/dist/esm/index.mjs +2 -2
  23. package/dist/esm/index.native.js +2 -2
  24. package/package.json +17 -17
  25. package/src/_withNativeStyle.tsx +141 -55
  26. package/src/helpers/nativeStyleEngine.ts +230 -101
  27. package/src/index.ts +1 -0
  28. package/src/setupHooks.ts +1 -0
  29. package/types/_withNativeStyle.d.ts +22 -2
  30. package/types/_withNativeStyle.d.ts.map +1 -1
  31. package/types/helpers/nativeStyleEngine.d.ts +24 -9
  32. package/types/helpers/nativeStyleEngine.d.ts.map +1 -1
  33. package/types/index.d.ts +1 -1
  34. package/types/index.d.ts.map +1 -1
  35. package/types/setupHooks.d.ts +1 -0
  36. package/types/setupHooks.d.ts.map +1 -1
@@ -20,6 +20,7 @@ var __copyProps = (to, from, except, desc) => {
20
20
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
21
  var nativeStyleEngine_exports = {};
22
22
  __export(nativeStyleEngine_exports, {
23
+ flushNativeStyleLinks: () => flushNativeStyleLinks,
23
24
  getNativeStyleEngine: () => getNativeStyleEngine,
24
25
  getNativeStyleEngineCacheStats: () => getNativeStyleEngineCacheStats,
25
26
  linkNativeStyleMapping: () => linkNativeStyleMapping,
@@ -84,8 +85,8 @@ let engine = null;
84
85
  const scopeStates = /* @__PURE__ */ new Map();
85
86
  const mappingKeys = /* @__PURE__ */ new WeakMap();
86
87
  const compiledMappings = /* @__PURE__ */ new Map();
87
- const activeCompiledMappings = /* @__PURE__ */ new Set();
88
- const processedBases = /* @__PURE__ */ new WeakMap();
88
+ const scopeMappings = /* @__PURE__ */ new Map();
89
+ let nextTableId = 1;
89
90
  function getCompiledMapping(mapping) {
90
91
  let key = mappingKeys.get(mapping);
91
92
  if (!key) {
@@ -97,7 +98,8 @@ function getCompiledMapping(mapping) {
97
98
  compiled = {
98
99
  mapping,
99
100
  states: /* @__PURE__ */ new Map(),
100
- links: /* @__PURE__ */ new Set()
101
+ tableId: nextTableId++,
102
+ sent: /* @__PURE__ */ new Map()
101
103
  };
102
104
  if (compiledMappings.size >= 1e4) {
103
105
  compiledMappings.clear();
@@ -118,9 +120,6 @@ function resolveCompiledMapping(compiled, stateName, theme) {
118
120
  const nativeProps = engine?.processStyleColors(renderProps) ?? renderProps;
119
121
  if (compiled.states.size >= 1e4) {
120
122
  compiled.states.clear();
121
- for (const link of compiled.links) {
122
- link.stateThemes.clear();
123
- }
124
123
  }
125
124
  const resolved = {
126
125
  theme,
@@ -130,10 +129,19 @@ function resolveCompiledMapping(compiled, stateName, theme) {
130
129
  compiled.states.set(stateName, resolved);
131
130
  return resolved;
132
131
  }
132
+ function syncTableState(compiled, stateName, theme) {
133
+ const resolved = resolveCompiledMapping(compiled, stateName, theme);
134
+ if (compiled.sent.get(stateName) === resolved) return;
135
+ compiled.sent.set(stateName, resolved);
136
+ engine.setTableState(compiled.tableId, stateName, resolved.nativeProps);
137
+ }
133
138
  function setNativeStyleEngine(next) {
134
139
  if (engine !== next) {
140
+ settleReleases();
135
141
  compiledMappings.clear();
136
- activeCompiledMappings.clear();
142
+ scopeMappings.clear();
143
+ pendingLinks = [];
144
+ unlinkedPending = 0;
137
145
  }
138
146
  engine = next;
139
147
  if (next) {
@@ -148,28 +156,18 @@ function getNativeStyleEngine() {
148
156
  function updateNativeStyleScope(scopeId, stateName, theme) {
149
157
  const previous = scopeStates.get(scopeId);
150
158
  if (previous?.name === stateName && previous.theme === theme) return;
159
+ flushNativeStyleLinks();
151
160
  scopeStates.set(scopeId, {
152
161
  name: stateName,
153
162
  theme
154
163
  });
155
164
  if (engine) {
156
- const entries = [];
157
- for (const compiled of activeCompiledMappings) {
158
- let props;
159
- for (const link of compiled.links) {
160
- if (link.scopeId !== scopeId) continue;
161
- const linkedTheme = link.stateThemes.get(stateName);
162
- if (linkedTheme === theme) continue;
163
- props ||= resolveCompiledMapping(compiled, stateName, theme).nativeProps;
164
- entries.push({
165
- id: link.handle.id,
166
- state: stateName,
167
- props
168
- });
169
- link.stateThemes.set(stateName, theme);
165
+ const linked = scopeMappings.get(scopeId);
166
+ if (linked) {
167
+ for (const compiled of linked.keys()) {
168
+ syncTableState(compiled, stateName, theme);
170
169
  }
171
170
  }
172
- if (entries.length) engine.updateViewStateTables(entries);
173
171
  }
174
172
  engine?.setStateName(stateName, scopeId);
175
173
  }
@@ -180,65 +178,138 @@ function removeNativeStyleScope(scopeId) {
180
178
  function resolveNativeStyleMapping(mapping, stateName, theme) {
181
179
  return resolveCompiledMapping(getCompiledMapping(mapping), stateName, theme).renderProps;
182
180
  }
183
- function linkNativeStyleMapping(ref, baseStyle, mapping, scopeId, stateName, theme) {
181
+ let pendingLinks = [];
182
+ let unlinkedPending = 0;
183
+ function trackScopeMapping(link, delta) {
184
+ let linked = scopeMappings.get(link.scopeId);
185
+ if (!linked) scopeMappings.set(link.scopeId, linked = /* @__PURE__ */ new Map());
186
+ const count = (linked.get(link.compiled) ?? 0) + delta;
187
+ if (count) {
188
+ linked.set(link.compiled, count);
189
+ } else {
190
+ linked.delete(link.compiled);
191
+ if (!linked.size) scopeMappings.delete(link.scopeId);
192
+ }
193
+ }
194
+ function flushNativeStyleLinks() {
195
+ settleReleases();
196
+ if (!pendingLinks.length) return;
197
+ const links = pendingLinks;
198
+ pendingLinks = [];
199
+ unlinkedPending = 0;
200
+ if (!engine) return;
201
+ const live = links.filter((link) => link.id === 0);
202
+ if (!live.length) return;
203
+ const refs = [];
204
+ const tableIds = [];
205
+ const scopeIndexes = [];
206
+ const scopes = [];
207
+ for (const link of live) {
208
+ let scopeIndex = scopes.indexOf(link.scopeId);
209
+ if (scopeIndex === -1) scopeIndex = scopes.push(link.scopeId) - 1;
210
+ refs.push(link.ref);
211
+ tableIds.push(link.compiled.tableId);
212
+ scopeIndexes.push(scopeIndex);
213
+ }
214
+ const firstId = engine.linkTables(refs, tableIds, scopeIndexes, scopes);
215
+ for (let i = 0; i < live.length; i++) {
216
+ const link = live[i];
217
+ link.id = firstId + i;
218
+ link.owner = engine;
219
+ link.ref = null;
220
+ trackScopeMapping(link, 1);
221
+ }
222
+ }
223
+ const releases = /* @__PURE__ */ new Map();
224
+ let settleQueued = false;
225
+ function settleReleases() {
226
+ settleQueued = false;
227
+ if (!releases.size) return;
228
+ const settling = [...releases.values()];
229
+ releases.clear();
230
+ for (const release of settling) release.settle();
231
+ }
232
+ function releasable(ref, compiled, scopeId, id, settle) {
233
+ const handle = {
234
+ id,
235
+ unlink: () => {
236
+ const prior = releases.get(ref);
237
+ if (prior && prior.handle !== handle) prior.settle();
238
+ releases.set(ref, {
239
+ compiled,
240
+ scopeId,
241
+ handle,
242
+ settle
243
+ });
244
+ if (!settleQueued) {
245
+ settleQueued = true;
246
+ queueMicrotask(settleReleases);
247
+ }
248
+ }
249
+ };
250
+ return handle;
251
+ }
252
+ function linkNativeStyleMapping(ref, mapping, scopeId, stateName, theme) {
184
253
  if (!engine) return null;
185
254
  const compiled = getCompiledMapping(mapping);
186
255
  const scopeState = scopeStates.get(scopeId);
187
- const currentStateName = scopeState?.name ?? stateName;
188
- const currentTheme = scopeState?.theme ?? theme;
189
- const stale = currentStateName !== stateName || currentTheme !== theme;
190
- const stateProps = resolveCompiledMapping(compiled, currentStateName, currentTheme).nativeProps;
191
- let base = processedBases.get(baseStyle);
192
- if (!base || base.engine !== engine) {
193
- base = {
194
- engine,
195
- props: engine.processStyleColors(normalizeNativeStyle(baseStyle))
196
- };
197
- processedBases.set(baseStyle, base);
256
+ const stale = scopeState && (scopeState.name !== stateName || scopeState.theme !== theme);
257
+ const kept = releases.get(ref);
258
+ if (kept) {
259
+ releases.delete(ref);
260
+ if (!stale && kept.compiled === compiled && kept.scopeId === scopeId) return kept.handle;
261
+ kept.settle();
198
262
  }
199
- const state = {};
200
- const stateThemes = /* @__PURE__ */ new Map();
201
- for (const [name, cached] of compiled.states) {
202
- state[name] = cached.nativeProps;
203
- stateThemes.set(name, cached.theme);
204
- }
205
- state[currentStateName] = stateProps;
206
- stateThemes.set(currentStateName, currentTheme);
207
- const handle = engine.link(ref, {
208
- base: base.props,
209
- state
210
- }, scopeId);
211
- if (!handle) return null;
212
263
  if (stale) {
213
- engine.updateViewStateTables([{
264
+ syncTableState(compiled, scopeState.name, scopeState.theme);
265
+ const handle = engine.link(ref, compiled.tableId, scopeId, true);
266
+ if (!handle) return null;
267
+ const link2 = {
268
+ ref: null,
269
+ compiled,
270
+ scopeId,
214
271
  id: handle.id,
215
- state: currentStateName,
216
- props: stateProps
217
- }]);
272
+ owner: engine
273
+ };
274
+ trackScopeMapping(link2, 1);
275
+ return releasable(ref, compiled, scopeId, handle.id, () => {
276
+ if (link2.id === -1) return;
277
+ link2.id = -1;
278
+ if (link2.owner === engine) trackScopeMapping(link2, -1);
279
+ handle.unlink();
280
+ });
218
281
  }
282
+ syncTableState(compiled, stateName, theme);
219
283
  const link = {
220
- handle,
284
+ ref,
285
+ compiled,
221
286
  scopeId,
222
- stateThemes
287
+ id: 0,
288
+ owner: null
223
289
  };
224
- compiled.links.add(link);
225
- activeCompiledMappings.add(compiled);
226
- return {
227
- id: handle.id,
228
- unlink: () => {
229
- compiled.links.delete(link);
230
- if (!compiled.links.size) {
231
- activeCompiledMappings.delete(compiled);
232
- }
233
- handle.unlink();
290
+ pendingLinks.push(link);
291
+ return releasable(ref, compiled, scopeId, 0, () => {
292
+ const id = link.id;
293
+ if (id === -1) return;
294
+ link.id = -1;
295
+ link.ref = null;
296
+ if (id > 0) {
297
+ if (link.owner === engine) trackScopeMapping(link, -1);
298
+ link.owner.unlink(id);
299
+ } else if (++unlinkedPending > 512 && unlinkedPending * 2 > pendingLinks.length) {
300
+ pendingLinks = pendingLinks.filter((pending2) => pending2.id === 0);
301
+ unlinkedPending = 0;
234
302
  }
235
- };
303
+ });
236
304
  }
237
- const getNativeStyleEngineCacheStats = () => ({
238
- mappings: compiledMappings.size,
239
- activeMappings: activeCompiledMappings.size,
240
- states: [.../* @__PURE__ */ new Set([...compiledMappings.values(), ...activeCompiledMappings])].reduce((total, compiled) => total + compiled.states.size, 0)
241
- });
305
+ const getNativeStyleEngineCacheStats = () => {
306
+ const active = new Set([...scopeMappings.values()].flatMap((linked) => [...linked.keys()]));
307
+ return {
308
+ mappings: compiledMappings.size,
309
+ activeMappings: active.size,
310
+ states: [.../* @__PURE__ */ new Set([...compiledMappings.values(), ...active])].reduce((total, compiled) => total + compiled.states.size, 0)
311
+ };
312
+ };
242
313
  let pending = null;
243
314
  let flushListener = null;
244
315
  function setNativeStyleEngineFlushListener(cb) {
@@ -22,6 +22,7 @@ var __copyProps = (to, from, except, desc) => {
22
22
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
23
23
  var nativeStyleEngine_exports = {};
24
24
  __export(nativeStyleEngine_exports, {
25
+ flushNativeStyleLinks: () => flushNativeStyleLinks,
25
26
  getNativeStyleEngine: () => getNativeStyleEngine,
26
27
  getNativeStyleEngineCacheStats: () => getNativeStyleEngineCacheStats,
27
28
  linkNativeStyleMapping: () => linkNativeStyleMapping,
@@ -121,8 +122,8 @@ var engine = null;
121
122
  var scopeStates = /* @__PURE__ */ new Map();
122
123
  var mappingKeys = /* @__PURE__ */ new WeakMap();
123
124
  var compiledMappings = /* @__PURE__ */ new Map();
124
- var activeCompiledMappings = /* @__PURE__ */ new Set();
125
- var processedBases = /* @__PURE__ */ new WeakMap();
125
+ var scopeMappings = /* @__PURE__ */ new Map();
126
+ var nextTableId = 1;
126
127
  function getCompiledMapping(mapping) {
127
128
  var key = mappingKeys.get(mapping);
128
129
  if (!key) {
@@ -136,7 +137,8 @@ function getCompiledMapping(mapping) {
136
137
  compiled = {
137
138
  mapping,
138
139
  states: /* @__PURE__ */ new Map(),
139
- links: /* @__PURE__ */ new Set()
140
+ tableId: nextTableId++,
141
+ sent: /* @__PURE__ */ new Map()
140
142
  };
141
143
  if (compiledMappings.size >= 1e4) {
142
144
  compiledMappings.clear();
@@ -158,26 +160,6 @@ function resolveCompiledMapping(compiled, stateName, theme) {
158
160
  var nativeProps = (_engine_processStyleColors = engine === null || engine === void 0 ? void 0 : engine.processStyleColors(renderProps)) !== null && _engine_processStyleColors !== void 0 ? _engine_processStyleColors : renderProps;
159
161
  if (compiled.states.size >= 1e4) {
160
162
  compiled.states.clear();
161
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
162
- try {
163
- for (var _iterator = compiled.links[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
164
- var link = _step.value;
165
- link.stateThemes.clear();
166
- }
167
- } catch (err) {
168
- _didIteratorError = true;
169
- _iteratorError = err;
170
- } finally {
171
- try {
172
- if (!_iteratorNormalCompletion && _iterator.return != null) {
173
- _iterator.return();
174
- }
175
- } finally {
176
- if (_didIteratorError) {
177
- throw _iteratorError;
178
- }
179
- }
180
- }
181
163
  }
182
164
  var resolved = {
183
165
  theme,
@@ -187,10 +169,19 @@ function resolveCompiledMapping(compiled, stateName, theme) {
187
169
  compiled.states.set(stateName, resolved);
188
170
  return resolved;
189
171
  }
172
+ function syncTableState(compiled, stateName, theme) {
173
+ var resolved = resolveCompiledMapping(compiled, stateName, theme);
174
+ if (compiled.sent.get(stateName) === resolved) return;
175
+ compiled.sent.set(stateName, resolved);
176
+ engine.setTableState(compiled.tableId, stateName, resolved.nativeProps);
177
+ }
190
178
  function setNativeStyleEngine(next) {
191
179
  if (engine !== next) {
180
+ settleReleases();
192
181
  compiledMappings.clear();
193
- activeCompiledMappings.clear();
182
+ scopeMappings.clear();
183
+ pendingLinks = [];
184
+ unlinkedPending = 0;
194
185
  }
195
186
  engine = next;
196
187
  if (next) {
@@ -222,62 +213,35 @@ function getNativeStyleEngine() {
222
213
  function updateNativeStyleScope(scopeId, stateName, theme) {
223
214
  var previous = scopeStates.get(scopeId);
224
215
  if ((previous === null || previous === void 0 ? void 0 : previous.name) === stateName && previous.theme === theme) return;
216
+ flushNativeStyleLinks();
225
217
  scopeStates.set(scopeId, {
226
218
  name: stateName,
227
219
  theme
228
220
  });
229
221
  if (engine) {
230
- var entries = [];
231
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
232
- try {
233
- for (var _iterator = activeCompiledMappings[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
234
- var compiled = _step.value;
235
- var props = void 0;
236
- var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = void 0;
222
+ var linked = scopeMappings.get(scopeId);
223
+ if (linked) {
224
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
225
+ try {
226
+ for (var _iterator = linked.keys()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
227
+ var compiled = _step.value;
228
+ syncTableState(compiled, stateName, theme);
229
+ }
230
+ } catch (err) {
231
+ _didIteratorError = true;
232
+ _iteratorError = err;
233
+ } finally {
237
234
  try {
238
- for (var _iterator1 = compiled.links[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true) {
239
- var link = _step1.value;
240
- if (link.scopeId !== scopeId) continue;
241
- var linkedTheme = link.stateThemes.get(stateName);
242
- if (linkedTheme === theme) continue;
243
- props || (props = resolveCompiledMapping(compiled, stateName, theme).nativeProps);
244
- entries.push({
245
- id: link.handle.id,
246
- state: stateName,
247
- props
248
- });
249
- link.stateThemes.set(stateName, theme);
235
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
236
+ _iterator.return();
250
237
  }
251
- } catch (err) {
252
- _didIteratorError1 = true;
253
- _iteratorError1 = err;
254
238
  } finally {
255
- try {
256
- if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
257
- _iterator1.return();
258
- }
259
- } finally {
260
- if (_didIteratorError1) {
261
- throw _iteratorError1;
262
- }
239
+ if (_didIteratorError) {
240
+ throw _iteratorError;
263
241
  }
264
242
  }
265
243
  }
266
- } catch (err) {
267
- _didIteratorError = true;
268
- _iteratorError = err;
269
- } finally {
270
- try {
271
- if (!_iteratorNormalCompletion && _iterator.return != null) {
272
- _iterator.return();
273
- }
274
- } finally {
275
- if (_didIteratorError) {
276
- throw _iteratorError;
277
- }
278
- }
279
244
  }
280
- if (entries.length) engine.updateViewStateTables(entries);
281
245
  }
282
246
  engine === null || engine === void 0 ? void 0 : engine.setStateName(stateName, scopeId);
283
247
  }
@@ -288,32 +252,80 @@ function removeNativeStyleScope(scopeId) {
288
252
  function resolveNativeStyleMapping(mapping, stateName, theme) {
289
253
  return resolveCompiledMapping(getCompiledMapping(mapping), stateName, theme).renderProps;
290
254
  }
291
- function linkNativeStyleMapping(ref, baseStyle, mapping, scopeId, stateName, theme) {
292
- if (!engine) return null;
293
- var compiled = getCompiledMapping(mapping);
294
- var scopeState = scopeStates.get(scopeId);
295
- var _scopeState_name;
296
- var currentStateName = (_scopeState_name = scopeState === null || scopeState === void 0 ? void 0 : scopeState.name) !== null && _scopeState_name !== void 0 ? _scopeState_name : stateName;
297
- var _scopeState_theme;
298
- var currentTheme = (_scopeState_theme = scopeState === null || scopeState === void 0 ? void 0 : scopeState.theme) !== null && _scopeState_theme !== void 0 ? _scopeState_theme : theme;
299
- var stale = currentStateName !== stateName || currentTheme !== theme;
300
- var stateProps = resolveCompiledMapping(compiled, currentStateName, currentTheme).nativeProps;
301
- var base = processedBases.get(baseStyle);
302
- if (!base || base.engine !== engine) {
303
- base = {
304
- engine,
305
- props: engine.processStyleColors(normalizeNativeStyle(baseStyle))
306
- };
307
- processedBases.set(baseStyle, base);
255
+ var pendingLinks = [];
256
+ var unlinkedPending = 0;
257
+ function trackScopeMapping(link, delta) {
258
+ var linked = scopeMappings.get(link.scopeId);
259
+ if (!linked) scopeMappings.set(link.scopeId, linked = /* @__PURE__ */ new Map());
260
+ var _linked_get;
261
+ var count = ((_linked_get = linked.get(link.compiled)) !== null && _linked_get !== void 0 ? _linked_get : 0) + delta;
262
+ if (count) {
263
+ linked.set(link.compiled, count);
264
+ } else {
265
+ linked.delete(link.compiled);
266
+ if (!linked.size) scopeMappings.delete(link.scopeId);
308
267
  }
309
- var state = {};
310
- var stateThemes = /* @__PURE__ */ new Map();
268
+ }
269
+ function flushNativeStyleLinks() {
270
+ settleReleases();
271
+ if (!pendingLinks.length) return;
272
+ var links = pendingLinks;
273
+ pendingLinks = [];
274
+ unlinkedPending = 0;
275
+ if (!engine) return;
276
+ var live = links.filter(function(link2) {
277
+ return link2.id === 0;
278
+ });
279
+ if (!live.length) return;
280
+ var refs = [];
281
+ var tableIds = [];
282
+ var scopeIndexes = [];
283
+ var scopes = [];
284
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
285
+ try {
286
+ for (var _iterator = live[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
287
+ var link = _step.value;
288
+ var scopeIndex = scopes.indexOf(link.scopeId);
289
+ if (scopeIndex === -1) scopeIndex = scopes.push(link.scopeId) - 1;
290
+ refs.push(link.ref);
291
+ tableIds.push(link.compiled.tableId);
292
+ scopeIndexes.push(scopeIndex);
293
+ }
294
+ } catch (err) {
295
+ _didIteratorError = true;
296
+ _iteratorError = err;
297
+ } finally {
298
+ try {
299
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
300
+ _iterator.return();
301
+ }
302
+ } finally {
303
+ if (_didIteratorError) {
304
+ throw _iteratorError;
305
+ }
306
+ }
307
+ }
308
+ var firstId = engine.linkTables(refs, tableIds, scopeIndexes, scopes);
309
+ for (var i = 0; i < live.length; i++) {
310
+ var link1 = live[i];
311
+ link1.id = firstId + i;
312
+ link1.owner = engine;
313
+ link1.ref = null;
314
+ trackScopeMapping(link1, 1);
315
+ }
316
+ }
317
+ var releases = /* @__PURE__ */ new Map();
318
+ var settleQueued = false;
319
+ function settleReleases() {
320
+ settleQueued = false;
321
+ if (!releases.size) return;
322
+ var settling = [...releases.values()];
323
+ releases.clear();
311
324
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
312
325
  try {
313
- for (var _iterator = compiled.states[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
314
- var [name, cached] = _step.value;
315
- state[name] = cached.nativeProps;
316
- stateThemes.set(name, cached.theme);
326
+ for (var _iterator = settling[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
327
+ var release = _step.value;
328
+ release.settle();
317
329
  }
318
330
  } catch (err) {
319
331
  _didIteratorError = true;
@@ -329,43 +341,90 @@ function linkNativeStyleMapping(ref, baseStyle, mapping, scopeId, stateName, the
329
341
  }
330
342
  }
331
343
  }
332
- state[currentStateName] = stateProps;
333
- stateThemes.set(currentStateName, currentTheme);
334
- var handle = engine.link(ref, {
335
- base: base.props,
336
- state
337
- }, scopeId);
338
- if (!handle) return null;
344
+ }
345
+ function releasable(ref, compiled, scopeId, id, settle) {
346
+ var handle = {
347
+ id,
348
+ unlink: function() {
349
+ var prior = releases.get(ref);
350
+ if (prior && prior.handle !== handle) prior.settle();
351
+ releases.set(ref, {
352
+ compiled,
353
+ scopeId,
354
+ handle,
355
+ settle
356
+ });
357
+ if (!settleQueued) {
358
+ settleQueued = true;
359
+ queueMicrotask(settleReleases);
360
+ }
361
+ }
362
+ };
363
+ return handle;
364
+ }
365
+ function linkNativeStyleMapping(ref, mapping, scopeId, stateName, theme) {
366
+ if (!engine) return null;
367
+ var compiled = getCompiledMapping(mapping);
368
+ var scopeState = scopeStates.get(scopeId);
369
+ var stale = scopeState && (scopeState.name !== stateName || scopeState.theme !== theme);
370
+ var kept = releases.get(ref);
371
+ if (kept) {
372
+ releases.delete(ref);
373
+ if (!stale && kept.compiled === compiled && kept.scopeId === scopeId) return kept.handle;
374
+ kept.settle();
375
+ }
339
376
  if (stale) {
340
- engine.updateViewStateTables([{
377
+ syncTableState(compiled, scopeState.name, scopeState.theme);
378
+ var handle = engine.link(ref, compiled.tableId, scopeId, true);
379
+ if (!handle) return null;
380
+ var link = {
381
+ ref: null,
382
+ compiled,
383
+ scopeId,
341
384
  id: handle.id,
342
- state: currentStateName,
343
- props: stateProps
344
- }]);
385
+ owner: engine
386
+ };
387
+ trackScopeMapping(link, 1);
388
+ return releasable(ref, compiled, scopeId, handle.id, function() {
389
+ if (link.id === -1) return;
390
+ link.id = -1;
391
+ if (link.owner === engine) trackScopeMapping(link, -1);
392
+ handle.unlink();
393
+ });
345
394
  }
346
- var link = {
347
- handle,
395
+ syncTableState(compiled, stateName, theme);
396
+ var link1 = {
397
+ ref,
398
+ compiled,
348
399
  scopeId,
349
- stateThemes
400
+ id: 0,
401
+ owner: null
350
402
  };
351
- compiled.links.add(link);
352
- activeCompiledMappings.add(compiled);
353
- return {
354
- id: handle.id,
355
- unlink: function() {
356
- compiled.links.delete(link);
357
- if (!compiled.links.size) {
358
- activeCompiledMappings.delete(compiled);
359
- }
360
- handle.unlink();
403
+ pendingLinks.push(link1);
404
+ return releasable(ref, compiled, scopeId, 0, function() {
405
+ var id = link1.id;
406
+ if (id === -1) return;
407
+ link1.id = -1;
408
+ link1.ref = null;
409
+ if (id > 0) {
410
+ if (link1.owner === engine) trackScopeMapping(link1, -1);
411
+ link1.owner.unlink(id);
412
+ } else if (++unlinkedPending > 512 && unlinkedPending * 2 > pendingLinks.length) {
413
+ pendingLinks = pendingLinks.filter(function(pending2) {
414
+ return pending2.id === 0;
415
+ });
416
+ unlinkedPending = 0;
361
417
  }
362
- };
418
+ });
363
419
  }
364
420
  var getNativeStyleEngineCacheStats = function() {
421
+ var active = new Set([...scopeMappings.values()].flatMap(function(linked) {
422
+ return [...linked.keys()];
423
+ }));
365
424
  return {
366
425
  mappings: compiledMappings.size,
367
- activeMappings: activeCompiledMappings.size,
368
- states: [.../* @__PURE__ */ new Set([...compiledMappings.values(), ...activeCompiledMappings])].reduce(function(total, compiled) {
426
+ activeMappings: active.size,
427
+ states: [.../* @__PURE__ */ new Set([...compiledMappings.values(), ...active])].reduce(function(total, compiled) {
369
428
  return total + compiled.states.size;
370
429
  }, 0)
371
430
  };