@tamagui/native-registry 3.0.5 → 3.0.6

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.
@@ -14,10 +14,22 @@
14
14
  #include <react/renderer/uimanager/UIManagerBinding.h>
15
15
  #include <react/renderer/uimanager/primitives.h>
16
16
 
17
+ #include <algorithm>
17
18
  #include <cstring>
19
+ #include <optional>
18
20
  #include <unordered_set>
19
21
  #include <vector>
20
22
 
23
+ #ifdef __ANDROID__
24
+ #include <fbjni/fbjni.h>
25
+
26
+ #include <condition_variable>
27
+ #include <deque>
28
+ #include <mutex>
29
+ #include <thread>
30
+ #include <tuple>
31
+ #endif
32
+
21
33
  namespace margelo::nitro::tamagui::registry {
22
34
 
23
35
  using namespace facebook::react;
@@ -51,19 +63,23 @@ jsi::Value HybridTamaguiRegistry::link(jsi::Runtime& rt, const jsi::Value&,
51
63
 
52
64
  runtime_ = &rt;
53
65
 
54
- const double id = nextId_++;
55
- auto& view = views_[id];
56
- view.node = wrapper->shadowNode;
57
- view.scopeId = args[2].asString(rt).utf8(rt);
66
+ double id;
67
+ LinkedView* linked;
58
68
  if (args[1].isNumber()) {
59
69
  auto& table = tables_[args[1].asNumber()];
60
70
  if (!table) table = std::make_shared<Table>();
61
- view.table = table;
71
+ linked = &linkTableView(wrapper->shadowNode, table, args[2].asString(rt).utf8(rt));
72
+ id = tableViewIds_.at(&wrapper->shadowNode->getFamily());
62
73
  } else {
74
+ id = nextId_++;
75
+ linked = &views_[id];
76
+ linked->family = wrapper->shadowNode->getFamilyShared();
77
+ linked->scopeId = args[2].asString(rt).utf8(rt);
63
78
  auto slots = jsi::dynamicFromValue(rt, args[1]);
64
- view.baseProps = slots.getDefault("base", nullptr);
65
- view.stateProps = slots.getDefault("state", nullptr);
79
+ linked->baseProps = slots.getDefault("base", nullptr);
80
+ linked->stateProps = slots.getDefault("state", nullptr);
66
81
  }
82
+ auto& view = *linked;
67
83
 
68
84
  if (count > 3 && args[3].isBool() && args[3].getBool()) {
69
85
  if (const auto* name = viewStateName(view)) {
@@ -71,14 +87,15 @@ jsi::Value HybridTamaguiRegistry::link(jsi::Runtime& rt, const jsi::Value&,
71
87
  buildViewUpdate(view, *name, updates);
72
88
  commitUpdates(rt, updates);
73
89
  }
90
+ } else if (view.table) {
91
+ seedWarmProps(view, *wrapper->shadowNode);
74
92
  }
75
93
  return jsi::Value(id);
76
94
  }
77
95
 
78
96
  // links many views to shared tables in one call: entry i is shadow node
79
- // nodes[i] on table tableIds[i] under scope scopes[scopeIndexes[i]]. ids are
80
- // issued in order starting at the returned id; an entry without a live shadow
81
- // node still consumes its id and stays unlinked
97
+ // nodes[i] on table tableIds[i] under scope scopes[scopeIndexes[i]]. a family
98
+ // already linked to a table keeps its link and moves to the new entry
82
99
  jsi::Value HybridTamaguiRegistry::linkTables(jsi::Runtime& rt, const jsi::Value&,
83
100
  const jsi::Value* args, size_t count) {
84
101
  if (count < 4 || !args[0].isObject() || !args[1].isObject() ||
@@ -98,9 +115,6 @@ jsi::Value HybridTamaguiRegistry::linkTables(jsi::Runtime& rt, const jsi::Value&
98
115
  }
99
116
 
100
117
  const size_t size = nodes.size(rt);
101
- const double firstId = nextId_;
102
- nextId_ += static_cast<double>(size);
103
-
104
118
  std::shared_ptr<Table> table;
105
119
  double tableId = -1;
106
120
  for (size_t i = 0; i < size; i++) {
@@ -119,14 +133,71 @@ jsi::Value HybridTamaguiRegistry::linkTables(jsi::Runtime& rt, const jsi::Value&
119
133
  if (!entry) entry = std::make_shared<Table>();
120
134
  table = entry;
121
135
  }
136
+ seedWarmProps(linkTableView(
137
+ wrapper->shadowNode, table,
138
+ scopes.at(static_cast<size_t>(
139
+ scopeIndexes.getValueAtIndex(rt, i).asNumber()))),
140
+ *wrapper->shadowNode);
141
+ }
142
+ if (views_.size() > pruneAt_) pruneUnmounted(rt);
143
+ return jsi::Value::undefined();
144
+ }
122
145
 
123
- auto& view = views_[firstId + static_cast<double>(i)];
124
- view.node = wrapper->shadowNode;
125
- view.scopeId = scopes.at(
126
- static_cast<size_t>(scopeIndexes.getValueAtIndex(rt, i).asNumber()));
146
+ HybridTamaguiRegistry::LinkedView& HybridTamaguiRegistry::linkTableView(
147
+ const std::shared_ptr<const ShadowNode>& node,
148
+ const std::shared_ptr<Table>& table, std::string scopeId) {
149
+ auto [it, added] = tableViewIds_.try_emplace(&node->getFamily(), nextId_);
150
+ if (added) nextId_ += 1;
151
+ auto& view = views_[it->second];
152
+ if (view.table != table) {
127
153
  view.table = table;
154
+ view.warm = {};
128
155
  }
129
- return jsi::Value(firstId);
156
+ view.family = node->getFamilyShared();
157
+ view.scopeId = std::move(scopeId);
158
+ return view;
159
+ }
160
+
161
+ void HybridTamaguiRegistry::pruneUnmounted(jsi::Runtime& rt) {
162
+ auto binding = UIManagerBinding::getBinding(rt);
163
+ if (!binding) return;
164
+ std::unordered_set<const ShadowNodeFamily*> mounted;
165
+ mounted.reserve(views_.size() * 2);
166
+ std::vector<const ShadowNode*> stack;
167
+ binding->getUIManager().getShadowTreeRegistry().enumerate(
168
+ [&](const ShadowTree& tree, bool& /*stop*/) {
169
+ stack.push_back(tree.getCurrentRevision().rootShadowNode.get());
170
+ while (!stack.empty()) {
171
+ const ShadowNode* node = stack.back();
172
+ stack.pop_back();
173
+ mounted.insert(&node->getFamily());
174
+ for (const auto& child : node->getChildren()) {
175
+ stack.push_back(child.get());
176
+ }
177
+ }
178
+ });
179
+ for (auto it = views_.begin(); it != views_.end();) {
180
+ const auto* family = it->second.family.get();
181
+ if (mounted.count(family)) {
182
+ ++it;
183
+ continue;
184
+ }
185
+ if (it->second.table) tableViewIds_.erase(family);
186
+ it = views_.erase(it);
187
+ }
188
+ pruneAt_ = std::max<size_t>(1024, views_.size() * 2);
189
+ }
190
+
191
+ // a view links right after React rendered it with its scope's current state
192
+ // (a render that raced a scope change links with commitNow instead), so the
193
+ // props it carries are that state's props, and a switch back reuses them
194
+ void HybridTamaguiRegistry::seedWarmProps(LinkedView& view,
195
+ const ShadowNode& node) const {
196
+ const auto* name = activeStateName(view.scopeId);
197
+ if (!name) return;
198
+ const auto& props = node.getProps();
199
+ view.warm.last = props;
200
+ view.warm.byState[*name] = props;
130
201
  }
131
202
 
132
203
  const std::string* HybridTamaguiRegistry::viewStateName(
@@ -136,7 +207,10 @@ const std::string* HybridTamaguiRegistry::viewStateName(
136
207
  }
137
208
 
138
209
  void HybridTamaguiRegistry::unlink(double id) {
139
- views_.erase(id);
210
+ auto it = views_.find(id);
211
+ if (it == views_.end()) return;
212
+ if (it->second.table) tableViewIds_.erase(it->second.family.get());
213
+ views_.erase(it);
140
214
  }
141
215
 
142
216
  const std::string* HybridTamaguiRegistry::activeStateName(
@@ -198,34 +272,18 @@ double HybridTamaguiRegistry::getMissCount() {
198
272
  namespace {
199
273
 
200
274
  using LeafUpdates = HybridTamaguiRegistry::LeafUpdates;
275
+ using Children = std::vector<std::shared_ptr<const ShadowNode>>;
201
276
  using AffectedNodes =
202
277
  std::unordered_map<const ShadowNodeFamily*, std::unordered_set<size_t>>;
203
278
 
204
- // records, for every ancestor of an updated view, which children lead to one.
205
- // returns whether `node` is or contains an updated view
206
- bool collectAffected(const ShadowNode& node, const LeafUpdates& updates,
207
- AffectedNodes& affected) {
208
- bool hit = updates.contains(&node.getFamily());
209
- const auto& children = node.getChildren();
210
- for (size_t index = 0; index < children.size(); index++) {
211
- if (collectAffected(*children[index], updates, affected)) {
212
- affected[&node.getFamily()].insert(index);
213
- hit = true;
214
- }
215
- }
216
- return hit;
217
- }
218
-
219
- AffectedNodes findAffectedNodes(const RootShadowNode& root,
220
- const LeafUpdates& updates) {
279
+ // for a few updates, which children of each ancestor lead to an updated view.
280
+ // getAncestors scans each parent's children to find the child, so many
281
+ // updates under one wide parent (a long list) cost updates x siblings: past a
282
+ // few updates the clone walks the tree once instead (nullopt)
283
+ std::optional<AffectedNodes> findAffectedNodes(const RootShadowNode& root,
284
+ const LeafUpdates& updates) {
285
+ if (updates.size() > 32) return std::nullopt;
221
286
  AffectedNodes affected;
222
- // getAncestors scans each parent's children to find the child, so many
223
- // updates under one wide parent (a long list) cost updates x siblings; past
224
- // a few updates one walk of the tree is cheaper
225
- if (updates.size() > 32) {
226
- collectAffected(root, updates, affected);
227
- return affected;
228
- }
229
287
  for (const auto& [family, update] : updates) {
230
288
  // families of unmounted views have no ancestors in this root: skipped
231
289
  for (const auto& [parentNode, childIndex] : family->getAncestors(root)) {
@@ -291,23 +349,29 @@ std::shared_ptr<ShadowNode> restyleParagraph(const ShadowNode& node,
291
349
  return clone;
292
350
  }
293
351
 
352
+ // clones `node` with the updated views under it, null when none is under it.
353
+ // with `affected` it descends only into the children recorded there
294
354
  std::shared_ptr<ShadowNode> cloneSubtree(const ShadowNode& node,
295
355
  const LeafUpdates& updates,
296
- const AffectedNodes& affected) {
356
+ const AffectedNodes* affected) {
297
357
  const auto* family = &node.getFamily();
298
358
 
299
359
  // only an ancestor of an updated view gets new children: RN dirties the
300
360
  // layout of any measurable node (text) cloned with a children fragment,
301
361
  // so passing them to the updated views themselves would re-measure every
302
362
  // text and re-run layout for a color change
303
- auto children = ShadowNodeFragment::childrenPlaceholder();
304
- if (auto it = affected.find(family); it != affected.end()) {
305
- auto cloned = node.getChildren();
306
- for (auto index : it->second) {
307
- cloned[index] = cloneSubtree(*cloned[index], updates, affected);
363
+ const auto& current = node.getChildren();
364
+ std::shared_ptr<Children> children;
365
+ const auto cloneChild = [&](size_t index) {
366
+ if (auto child = cloneSubtree(*current[index], updates, affected)) {
367
+ if (!children) children = std::make_shared<Children>(current);
368
+ (*children)[index] = std::move(child);
308
369
  }
309
- children = std::make_shared<std::vector<std::shared_ptr<const ShadowNode>>>(
310
- std::move(cloned));
370
+ };
371
+ if (!affected) {
372
+ for (size_t index = 0; index < current.size(); index++) cloneChild(index);
373
+ } else if (auto it = affected->find(family); it != affected->end()) {
374
+ for (auto index : it->second) cloneChild(index);
311
375
  }
312
376
 
313
377
  Props::Shared newProps = ShadowNodeFragment::propsPlaceholder();
@@ -319,10 +383,7 @@ std::shared_ptr<ShadowNode> cloneSubtree(const ShadowNode& node,
319
383
  RawProps(update.props()));
320
384
  };
321
385
  if (auto* warm = update.warm) {
322
- if (warm->last != node.getProps() || warm->revision != update.revision) {
323
- warm->byState.clear();
324
- warm->revision = update.revision;
325
- }
386
+ if (warm->last != node.getProps()) warm->byState.clear();
326
387
  auto& props = warm->byState[*update.state];
327
388
  if (!props) props = parse();
328
389
  warm->last = props;
@@ -333,15 +394,69 @@ std::shared_ptr<ShadowNode> cloneSubtree(const ShadowNode& node,
333
394
  if (auto restyled = restyleParagraph(node, newProps)) {
334
395
  return restyled;
335
396
  }
397
+ } else if (!children) {
398
+ return nullptr;
336
399
  }
337
400
 
338
401
  return node.clone({
339
402
  .props = newProps,
340
- .children = children,
403
+ .children = children ? children : ShadowNodeFragment::childrenPlaceholder(),
341
404
  .state = ShadowNodeFragment::statePlaceholder(),
342
405
  });
343
406
  }
344
407
 
408
+ #ifdef __ANDROID__
409
+ // android pulls a commit's mount transaction (the tree diff, then a jni prop
410
+ // map per updated view) on the committing thread, and a theme change updates
411
+ // every view. the engine commits on the js thread with the tree's mounting
412
+ // suspended, which keeps the clones taking over React's handles there, and
413
+ // this thread resumes it: resuming mounts the latest revision, off the js
414
+ // thread. a react commit landing in between mounts with it
415
+ class MountThread {
416
+ public:
417
+ static void resume(std::shared_ptr<UIManagerBinding> binding,
418
+ SurfaceId surfaceId) {
419
+ // never destroyed: the thread outlives every registry
420
+ static auto* thread = new MountThread();
421
+ {
422
+ std::lock_guard<std::mutex> lock(thread->mutex_);
423
+ thread->surfaces_.emplace_back(std::move(binding), surfaceId);
424
+ }
425
+ thread->ready_.notify_one();
426
+ }
427
+
428
+ private:
429
+ MountThread() {
430
+ std::thread([this] {
431
+ facebook::jni::ThreadScope::WithClassLoader([this] { run(); });
432
+ }).detach();
433
+ }
434
+
435
+ void run() {
436
+ for (;;) {
437
+ std::shared_ptr<UIManagerBinding> binding;
438
+ SurfaceId surfaceId;
439
+ {
440
+ std::unique_lock<std::mutex> lock(mutex_);
441
+ ready_.wait(lock, [this] { return !surfaces_.empty(); });
442
+ std::tie(binding, surfaceId) = std::move(surfaces_.front());
443
+ surfaces_.pop_front();
444
+ }
445
+ // a stopped surface is gone from the registry, and visiting holds the
446
+ // registry so the tree cannot stop mid-mount
447
+ binding->getUIManager().getShadowTreeRegistry().visit(
448
+ surfaceId, [](const ShadowTree& tree) {
449
+ tree.setCommitMode(ShadowTree::CommitMode::Normal);
450
+ });
451
+ }
452
+ }
453
+
454
+ std::mutex mutex_;
455
+ std::condition_variable ready_;
456
+ std::deque<std::pair<std::shared_ptr<UIManagerBinding>, SurfaceId>> surfaces_;
457
+ };
458
+ #endif
459
+
345
460
  } // namespace
346
461
 
347
462
  // merge base + the named state's props for one view into `out`. a runtime
@@ -362,7 +477,6 @@ bool HybridTamaguiRegistry::buildViewUpdate(LinkedView& view,
362
477
  update.shared = &it->second;
363
478
  update.warm = &view.warm;
364
479
  update.state = &it->first.getString();
365
- update.revision = view.table->revision;
366
480
  } else {
367
481
  auto& props = update.owned;
368
482
  props = view.baseProps.isObject() ? view.baseProps : folly::dynamic::object();
@@ -383,7 +497,7 @@ bool HybridTamaguiRegistry::buildViewUpdate(LinkedView& view,
383
497
  }
384
498
  const auto& props = update.props();
385
499
 
386
- const auto& family = view.node->getFamily();
500
+ const auto& family = *view.family;
387
501
  // the retained node keeps its family alive; unmounted views resolve to
388
502
  // no ancestors during the transaction and are skipped safely
389
503
  if (view.table) {
@@ -427,19 +541,32 @@ void HybridTamaguiRegistry::commitUpdates(jsi::Runtime& rt,
427
541
  ShadowNode::getUseRuntimeShadowNodeReferenceUpdateOnThread();
428
542
  ShadowNode::setUseRuntimeShadowNodeReferenceUpdateOnThread(true);
429
543
  binding->getUIManager().getShadowTreeRegistry().enumerate(
430
- [this, &updates](const ShadowTree& tree, bool& /*stop*/) {
544
+ [&](const ShadowTree& tree, bool& /*stop*/) {
545
+ #ifdef __ANDROID__
546
+ // a tree already suspended (a queued resume, or a surface not yet
547
+ // mountable) mounts when its suspender resumes it
548
+ const bool mountOffThread =
549
+ tree.getCommitMode() == ShadowTree::CommitMode::Normal;
550
+ if (mountOffThread) {
551
+ tree.setCommitMode(ShadowTree::CommitMode::Suspended);
552
+ }
553
+ #endif
431
554
  auto status = tree.commit(
432
555
  [&updates](const RootShadowNode& oldRoot)
433
556
  -> RootShadowNode::Unshared {
434
557
  auto affected = findAffectedNodes(oldRoot, updates);
435
- if (affected.empty()) return nullptr;
436
- return std::static_pointer_cast<RootShadowNode>(
437
- cloneSubtree(oldRoot, updates, affected));
558
+ return std::static_pointer_cast<RootShadowNode>(cloneSubtree(
559
+ oldRoot, updates, affected ? &*affected : nullptr));
438
560
  },
439
561
  {.enableStateReconciliation = false, .mountSynchronously = true});
440
562
  if (status == ShadowTree::CommitStatus::Succeeded) {
441
563
  commitCount_ += 1;
442
564
  }
565
+ #ifdef __ANDROID__
566
+ if (mountOffThread) {
567
+ MountThread::resume(binding, tree.getSurfaceId());
568
+ }
569
+ #endif
443
570
  });
444
571
  ShadowNode::setUseRuntimeShadowNodeReferenceUpdateOnThread(updatedReferences);
445
572
  }
@@ -528,12 +655,16 @@ jsi::Value HybridTamaguiRegistry::setTableState(jsi::Runtime& rt,
528
655
  auto& table = tables_[args[0].asNumber()];
529
656
  if (!table) table = std::make_shared<Table>();
530
657
  const std::string stateName = args[1].asString(rt).utf8(rt);
531
- table->states[stateName] = jsi::dynamicFromValue(rt, args[2]);
532
- table->revision += 1;
658
+ auto props = jsi::dynamicFromValue(rt, args[2]);
659
+ auto& entry = table->states[stateName];
660
+ // a resend of the same values changes nothing and keeps the parsed props
661
+ if (entry == props) return jsi::Value::undefined();
662
+ entry = std::move(props);
533
663
 
534
664
  LeafUpdates updates;
535
665
  for (auto& [id, view] : views_) {
536
666
  if (view.table != table) continue;
667
+ view.warm.byState.erase(stateName);
537
668
  const auto* name = viewStateName(view);
538
669
  if (name && *name == stateName) buildViewUpdate(view, stateName, updates);
539
670
  }
@@ -561,7 +692,7 @@ jsi::Value HybridTamaguiRegistry::getViewState(jsi::Runtime& rt,
561
692
  : folly::dynamic(nullptr);
562
693
  return jsi::valueFromDynamic(rt, out);
563
694
  }
564
- const auto& family = view.node->getFamily();
695
+ const auto& family = *view.family;
565
696
  std::lock_guard<std::mutex> lock(family.nativePropsMutex);
566
697
  out["nativeProps"] = family.nativeProps_DEPRECATED
567
698
  ? *family.nativeProps_DEPRECATED
@@ -6,7 +6,6 @@
6
6
  #include <jsi/jsi.h>
7
7
  #include <react/renderer/core/ShadowNode.h>
8
8
 
9
- #include <cstdint>
10
9
  #include <memory>
11
10
  #include <mutex>
12
11
  #include <string>
@@ -44,13 +43,13 @@ class HybridTamaguiRegistry : public HybridTamaguiRegistrySpec {
44
43
  // one view's props for a commit. table views point at their table's
45
44
  // state entry, shared by every view of the table, so the commit can parse
46
45
  // each distinct (props, update) pair once; per-view slots own theirs
47
- // the props a table view committed per state. while the node still carries
48
- // the props this engine committed last, a switch back to a state reuses
49
- // that state's props instead of parsing them again; a React render or a
50
- // table refill invalidates them
46
+ // the props a table view carries per state: the props React rendered for
47
+ // the state it linked in, and the props this engine committed since. while
48
+ // the node still carries the props `last` names, a switch back to a state
49
+ // reuses that state's props instead of parsing them again; a React render
50
+ // invalidates them all, a table refill the refilled state's
51
51
  struct WarmProps {
52
52
  facebook::react::Props::Shared last;
53
- uint64_t revision = 0;
54
53
  std::unordered_map<std::string, facebook::react::Props::Shared> byState;
55
54
  };
56
55
 
@@ -60,7 +59,6 @@ class HybridTamaguiRegistry : public HybridTamaguiRegistrySpec {
60
59
  // table views only
61
60
  WarmProps* warm = nullptr;
62
61
  const std::string* state = nullptr;
63
- uint64_t revision = 0;
64
62
  const folly::dynamic& props() const { return shared ? *shared : owned; }
65
63
  };
66
64
  using LeafUpdates =
@@ -84,14 +82,14 @@ class HybridTamaguiRegistry : public HybridTamaguiRegistrySpec {
84
82
  // name -> props. filled once per mapping and state, never per view
85
83
  struct Table {
86
84
  folly::dynamic states = folly::dynamic::object();
87
- // bumped on every refill so views drop props parsed from older states
88
- uint64_t revision = 0;
89
85
  };
90
86
 
91
87
  struct LinkedView {
92
88
  // retained so the family stays valid for in-transaction ancestor lookup;
93
- // unmounted views resolve to no ancestors and are skipped
94
- std::shared_ptr<const facebook::react::ShadowNode> node;
89
+ // unmounted views resolve to no ancestors and are skipped. the family,
90
+ // never a node: a retained node would keep its whole unmounted subtree
91
+ // alive until the prune
92
+ facebook::react::ShadowNodeFamily::Shared family;
95
93
  std::string scopeId;
96
94
  folly::dynamic baseProps; // object, or nullptr when absent
97
95
  folly::dynamic stateProps; // stateName -> props object, or nullptr
@@ -111,13 +109,17 @@ class HybridTamaguiRegistry : public HybridTamaguiRegistrySpec {
111
109
  jsi::Value link(jsi::Runtime& rt, const jsi::Value& thisValue,
112
110
  const jsi::Value* args, size_t count);
113
111
 
112
+ // raw JSI: linkTables(nodes, tableIds, scopeIndexes, scopes) -> void
113
+ // links many views to shared tables; a view already linked to a table
114
+ // moves to its new entry. table links are never unlinked by id: views that
115
+ // left the tree are pruned here once the linked count doubles
116
+ jsi::Value linkTables(jsi::Runtime& rt, const jsi::Value& thisValue,
117
+ const jsi::Value* args, size_t count);
118
+
114
119
  // raw JSI: applyViewStates([{id, state, props?}]) -> void
115
120
  // batched per-view state selection: for each entry, `props` (when given)
116
121
  // replaces the view's state table entry under `state`, the view's active
117
122
  // state becomes `state`, and all changed views commit in ONE transaction.
118
- jsi::Value linkTables(jsi::Runtime& rt, const jsi::Value& thisValue,
119
- const jsi::Value* args, size_t count);
120
-
121
123
  jsi::Value applyViewStates(jsi::Runtime& rt, const jsi::Value& thisValue,
122
124
  const jsi::Value* args, size_t count);
123
125
 
@@ -131,6 +133,13 @@ class HybridTamaguiRegistry : public HybridTamaguiRegistrySpec {
131
133
  jsi::Value getViewState(jsi::Runtime& rt, const jsi::Value& thisValue,
132
134
  const jsi::Value* args, size_t count);
133
135
 
136
+ // links a shadow node to a shared table, reusing its family's link
137
+ LinkedView& linkTableView(const std::shared_ptr<const facebook::react::ShadowNode>& node,
138
+ const std::shared_ptr<Table>& table, std::string scopeId);
139
+
140
+ // drops linked views whose family is in no shadow tree
141
+ void pruneUnmounted(jsi::Runtime& rt);
142
+
134
143
  // resolve the active state name for a scope: scope entry, else root
135
144
  const std::string* activeStateName(const std::string& scopeId) const;
136
145
 
@@ -148,7 +157,13 @@ class HybridTamaguiRegistry : public HybridTamaguiRegistrySpec {
148
157
  // the state a view shows right now: its own runtime state, else its scope's
149
158
  const std::string* viewStateName(const LinkedView& view) const;
150
159
 
160
+ // records a freshly linked table view's React props as its state's props
161
+ void seedWarmProps(LinkedView& view, const facebook::react::ShadowNode& node) const;
162
+
151
163
  std::unordered_map<double, LinkedView> views_;
164
+ // table views by family: a host attaching again keeps one link
165
+ std::unordered_map<const facebook::react::ShadowNodeFamily*, double> tableViewIds_;
166
+ size_t pruneAt_ = 1024;
152
167
  std::unordered_map<double, std::shared_ptr<Table>> tables_;
153
168
  std::unordered_map<std::string, std::string> scopeStates_; // "" = root
154
169
  double nextId_ = 1;
@@ -44,9 +44,7 @@ function isAvailable() {
44
44
  function link(_ref, _table, _scopeId, _commitNow) {
45
45
  return null;
46
46
  }
47
- function linkTables(_refs, _tableIds, _scopeIndexes, _scopes) {
48
- return 0;
49
- }
47
+ function linkTables(_refs, _tableIds, _scopeIndexes, _scopes) {}
50
48
  function unlink(_id) {}
51
49
  function applyViewStates(_entries) {}
52
50
  function setTableState(_tableId, _state, _props) {}
@@ -89,7 +89,7 @@ function linkTables(refs, tableIds, scopeIndexes, scopes) {
89
89
  for (var i = 0; i < refs.length; i++) {
90
90
  nodes[i] = getShadowNode(refs[i]);
91
91
  }
92
- return getEngine().linkTables(nodes, tableIds, scopeIndexes, scopes);
92
+ getEngine().linkTables(nodes, tableIds, scopeIndexes, scopes);
93
93
  }
94
94
  function unlink(id) {
95
95
  getEngine().unlink(id);
@@ -89,7 +89,7 @@ function linkTables(refs, tableIds, scopeIndexes, scopes) {
89
89
  for (var i = 0; i < refs.length; i++) {
90
90
  nodes[i] = getShadowNode(refs[i]);
91
91
  }
92
- return getEngine().linkTables(nodes, tableIds, scopeIndexes, scopes);
92
+ getEngine().linkTables(nodes, tableIds, scopeIndexes, scopes);
93
93
  }
94
94
  function unlink(id) {
95
95
  getEngine().unlink(id);
@@ -1 +1 @@
1
- {"version":3,"file":"index.native.js","names":[],"sources":["cjs/index.native.js"],"sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\nvar index_native_exports = {};\n__export(index_native_exports, {\n ROOT_SCOPE: () => import_mirror2.ROOT_SCOPE,\n applyViewStates: () => applyViewStates,\n getMirroredStateName: () => import_mirror2.getMirroredStateName,\n getStats: () => getStats,\n getViewState: () => getViewState,\n isAvailable: () => isAvailable,\n link: () => link,\n linkTables: () => linkTables,\n processStyleColors: () => import_processStyleColors.processStyleColors,\n removeScope: () => removeScope,\n resolveSlots: () => resolveSlots,\n setStateName: () => setStateName,\n setTableState: () => setTableState,\n unlink: () => unlink\n});\nmodule.exports = __toCommonJS(index_native_exports);\nvar import_react_native_nitro_modules = require(\"react-native-nitro-modules\");\nvar import_mirror = require(\"./mirror\");\nvar import_mirror2 = require(\"./mirror\");\nvar import_processStyleColors = require(\"./processStyleColors.native\");\nvar engine = null;\nvar initError = null;\ntry {\n engine = import_react_native_nitro_modules.NitroModules.createHybridObject(\"TamaguiRegistry\");\n} catch (error) {\n initError = error;\n}\nfunction isAvailable() {\n return engine !== null;\n}\nfunction getEngine() {\n if (engine) return engine;\n var detail = initError instanceof Error ? ` ${initError.message}` : \"\";\n throw new Error(`[@tamagui/native-registry] TamaguiRegistry failed to initialize; is react-native-nitro-modules installed and the app rebuilt?${detail}`);\n}\nfunction getShadowNode(ref) {\n var _handle_stateNode;\n var handle = ref === null || ref === void 0 ? void 0 : ref.__internalInstanceHandle;\n var _handle_stateNode_node;\n return (_handle_stateNode_node = handle === null || handle === void 0 ? void 0 : (_handle_stateNode = handle.stateNode) === null || _handle_stateNode === void 0 ? void 0 : _handle_stateNode.node) !== null && _handle_stateNode_node !== void 0 ? _handle_stateNode_node : null;\n}\nfunction isNitroHybridView(ref) {\n var config = ref === null || ref === void 0 ? void 0 : ref.__viewConfig;\n return !!(config === null || config === void 0 ? void 0 : config.validAttributes) && \"hybridRef\" in config.validAttributes;\n}\nfunction link(ref, table) {\n var scopeId = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : import_mirror.ROOT_SCOPE, commitNow = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : false;\n if (isNitroHybridView(ref)) return null;\n var node = getShadowNode(ref);\n if (!node) return null;\n var e = getEngine();\n var id = e.link(node, table, scopeId, commitNow);\n var unlinked = false;\n return {\n id,\n unlink: function() {\n if (unlinked) return;\n unlinked = true;\n e.unlink(id);\n }\n };\n}\nfunction linkTables(refs, tableIds, scopeIndexes, scopes) {\n var nodes = new Array(refs.length);\n for (var i = 0; i < refs.length; i++) {\n nodes[i] = getShadowNode(refs[i]);\n }\n return getEngine().linkTables(nodes, tableIds, scopeIndexes, scopes);\n}\nfunction unlink(id) {\n getEngine().unlink(id);\n}\nfunction applyViewStates(entries) {\n if (entries.length === 0) return;\n getEngine().applyViewStates(entries);\n}\nfunction setTableState(tableId, state, props) {\n getEngine().setTableState(tableId, state, props);\n}\nfunction setStateName(stateName) {\n var scopeId = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : import_mirror.ROOT_SCOPE;\n (0, import_mirror.setMirroredStateName)(scopeId, stateName);\n getEngine().setStateName(scopeId, stateName);\n}\nfunction removeScope(scopeId) {\n (0, import_mirror.removeMirroredScope)(scopeId);\n getEngine().removeScope(scopeId);\n}\nfunction resolveSlots(slots) {\n var scopeId = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : import_mirror.ROOT_SCOPE;\n var _slots_state;\n var name = (0, import_mirror.getMirroredStateName)(scopeId);\n return {\n ...slots.base,\n ...name ? (_slots_state = slots.state) === null || _slots_state === void 0 ? void 0 : _slots_state[name] : void 0\n };\n}\nfunction getViewState(id) {\n if (!engine) return null;\n return engine.getViewState(id);\n}\nfunction getStats() {\n if (!engine) return {\n viewCount: 0,\n commitCount: 0,\n missCount: 0\n };\n return {\n viewCount: engine.getViewCount(),\n commitCount: engine.getCommitCount(),\n missCount: engine.getMissCount()\n };\n}\n//# sourceMappingURL=index.native.js.map\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.native.js","names":[],"sources":["cjs/index.native.js"],"sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\nvar index_native_exports = {};\n__export(index_native_exports, {\n ROOT_SCOPE: () => import_mirror2.ROOT_SCOPE,\n applyViewStates: () => applyViewStates,\n getMirroredStateName: () => import_mirror2.getMirroredStateName,\n getStats: () => getStats,\n getViewState: () => getViewState,\n isAvailable: () => isAvailable,\n link: () => link,\n linkTables: () => linkTables,\n processStyleColors: () => import_processStyleColors.processStyleColors,\n removeScope: () => removeScope,\n resolveSlots: () => resolveSlots,\n setStateName: () => setStateName,\n setTableState: () => setTableState,\n unlink: () => unlink\n});\nmodule.exports = __toCommonJS(index_native_exports);\nvar import_react_native_nitro_modules = require(\"react-native-nitro-modules\");\nvar import_mirror = require(\"./mirror\");\nvar import_mirror2 = require(\"./mirror\");\nvar import_processStyleColors = require(\"./processStyleColors.native\");\nvar engine = null;\nvar initError = null;\ntry {\n engine = import_react_native_nitro_modules.NitroModules.createHybridObject(\"TamaguiRegistry\");\n} catch (error) {\n initError = error;\n}\nfunction isAvailable() {\n return engine !== null;\n}\nfunction getEngine() {\n if (engine) return engine;\n var detail = initError instanceof Error ? ` ${initError.message}` : \"\";\n throw new Error(`[@tamagui/native-registry] TamaguiRegistry failed to initialize; is react-native-nitro-modules installed and the app rebuilt?${detail}`);\n}\nfunction getShadowNode(ref) {\n var _handle_stateNode;\n var handle = ref === null || ref === void 0 ? void 0 : ref.__internalInstanceHandle;\n var _handle_stateNode_node;\n return (_handle_stateNode_node = handle === null || handle === void 0 ? void 0 : (_handle_stateNode = handle.stateNode) === null || _handle_stateNode === void 0 ? void 0 : _handle_stateNode.node) !== null && _handle_stateNode_node !== void 0 ? _handle_stateNode_node : null;\n}\nfunction isNitroHybridView(ref) {\n var config = ref === null || ref === void 0 ? void 0 : ref.__viewConfig;\n return !!(config === null || config === void 0 ? void 0 : config.validAttributes) && \"hybridRef\" in config.validAttributes;\n}\nfunction link(ref, table) {\n var scopeId = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : import_mirror.ROOT_SCOPE, commitNow = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : false;\n if (isNitroHybridView(ref)) return null;\n var node = getShadowNode(ref);\n if (!node) return null;\n var e = getEngine();\n var id = e.link(node, table, scopeId, commitNow);\n var unlinked = false;\n return {\n id,\n unlink: function() {\n if (unlinked) return;\n unlinked = true;\n e.unlink(id);\n }\n };\n}\nfunction linkTables(refs, tableIds, scopeIndexes, scopes) {\n var nodes = new Array(refs.length);\n for (var i = 0; i < refs.length; i++) {\n nodes[i] = getShadowNode(refs[i]);\n }\n getEngine().linkTables(nodes, tableIds, scopeIndexes, scopes);\n}\nfunction unlink(id) {\n getEngine().unlink(id);\n}\nfunction applyViewStates(entries) {\n if (entries.length === 0) return;\n getEngine().applyViewStates(entries);\n}\nfunction setTableState(tableId, state, props) {\n getEngine().setTableState(tableId, state, props);\n}\nfunction setStateName(stateName) {\n var scopeId = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : import_mirror.ROOT_SCOPE;\n (0, import_mirror.setMirroredStateName)(scopeId, stateName);\n getEngine().setStateName(scopeId, stateName);\n}\nfunction removeScope(scopeId) {\n (0, import_mirror.removeMirroredScope)(scopeId);\n getEngine().removeScope(scopeId);\n}\nfunction resolveSlots(slots) {\n var scopeId = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : import_mirror.ROOT_SCOPE;\n var _slots_state;\n var name = (0, import_mirror.getMirroredStateName)(scopeId);\n return {\n ...slots.base,\n ...name ? (_slots_state = slots.state) === null || _slots_state === void 0 ? void 0 : _slots_state[name] : void 0\n };\n}\nfunction getViewState(id) {\n if (!engine) return null;\n return engine.getViewState(id);\n}\nfunction getStats() {\n if (!engine) return {\n viewCount: 0,\n commitCount: 0,\n missCount: 0\n };\n return {\n viewCount: engine.getViewCount(),\n commitCount: engine.getCommitCount(),\n missCount: engine.getMissCount()\n };\n}\n//# sourceMappingURL=index.native.js.map\n"],"mappings":";;;AACA,IAAI,YAAY,OAAO;AACvB,IAAI,mBAAmB,OAAO;AAC9B,IAAI,oBAAoB,OAAO;AAC/B,IAAI,eAAe,OAAO,UAAU;AACpC,IAAI,YAAY,QAAQ,QAAQ;CAC9B,KAAK,IAAI,QAAQ,KACf,UAAU,QAAQ,MAAM;EAAE,KAAK,IAAI;EAAO,YAAY;CAAK,CAAC;AAChE;AACA,IAAI,eAAe,IAAI,MAAM,QAAQ,SAAS;CAC5C,IAAI,QAAQ,OAAO,SAAS,YAAY,OAAO,SAAS,YAAY;EAClE,KAAK,IAAI,OAAO,kBAAkB,IAAI,GACpC,IAAI,CAAC,aAAa,KAAK,IAAI,GAAG,KAAK,QAAQ,QACzC,UAAU,IAAI,KAAK;GAAE,WAAW,KAAK;GAAM,YAAY,EAAE,OAAO,iBAAiB,MAAM,GAAG,MAAM,KAAK;EAAW,CAAC;CACvH;CACA,OAAO;AACT;AACA,IAAI,gBAAgB,QAAQ,YAAY,UAAU,CAAC,GAAG,cAAc,EAAE,OAAO,KAAK,CAAC,GAAG,GAAG;AACzF,IAAI,uBAAuB,CAAC;AAC5B,SAAS,sBAAsB;CAC7B,kBAAkB,eAAe;CACjC,uBAAuB;CACvB,4BAA4B,eAAe;CAC3C,gBAAgB;CAChB,oBAAoB;CACpB,mBAAmB;CACnB,YAAY;CACZ,kBAAkB;CAClB,0BAA0B,0BAA0B;CACpD,mBAAmB;CACnB,oBAAoB;CACpB,oBAAoB;CACpB,qBAAqB;CACrB,cAAc;AAChB,CAAC;AACD,OAAO,UAAU,aAAa,oBAAoB;AAClD,IAAI,oCAAoC,QAAQ,4BAA4B;AAC5E,IAAI,gBAAgB,QAAQ,oBAAU;AACtC,IAAI,iBAAiB,QAAQ,oBAAU;AACvC,IAAI,4BAA4B,QAAQ,gCAA6B;AACrE,IAAI,SAAS;AACb,IAAI,YAAY;AAChB,IAAI;CACF,SAAS,kCAAkC,aAAa,mBAAmB,iBAAiB;AAC9F,SAAS,OAAO;CACd,YAAY;AACd;AACA,SAAS,cAAc;CACrB,OAAO,WAAW;AACpB;AACA,SAAS,YAAY;CACnB,IAAI,QAAQ,OAAO;CACnB,IAAI,SAAS,qBAAqB,QAAQ,IAAI,UAAU,YAAY;CACpE,MAAM,IAAI,MAAM,gIAAgI,QAAQ;AAC1J;AACA,SAAS,cAAc,KAAK;CAC1B,IAAI;CACJ,IAAI,SAAS,QAAQ,QAAQ,QAAQ,KAAK,IAAI,KAAK,IAAI,IAAI;CAC3D,IAAI;CACJ,QAAQ,yBAAyB,WAAW,QAAQ,WAAW,KAAK,IAAI,KAAK,KAAK,oBAAoB,OAAO,eAAe,QAAQ,sBAAsB,KAAK,IAAI,KAAK,IAAI,kBAAkB,UAAU,QAAQ,2BAA2B,KAAK,IAAI,yBAAyB;AAC/Q;AACA,SAAS,kBAAkB,KAAK;CAC9B,IAAI,SAAS,QAAQ,QAAQ,QAAQ,KAAK,IAAI,KAAK,IAAI,IAAI;CAC3D,OAAO,CAAC,EAAE,WAAW,QAAQ,WAAW,KAAK,IAAI,KAAK,IAAI,OAAO,oBAAoB,eAAe,OAAO;AAC7G;AACA,SAAS,KAAK,KAAK,OAAO;CACxB,IAAI,UAAU,UAAU,SAAS,KAAK,UAAU,OAAO,KAAK,IAAI,UAAU,KAAK,cAAc,YAAY,YAAY,UAAU,SAAS,KAAK,UAAU,OAAO,KAAK,IAAI,UAAU,KAAK;CACtL,IAAI,kBAAkB,GAAG,GAAG,OAAO;CACnC,IAAI,OAAO,cAAc,GAAG;CAC5B,IAAI,CAAC,MAAM,OAAO;CAClB,IAAI,IAAI,UAAU;CAClB,IAAI,KAAK,EAAE,KAAK,MAAM,OAAO,SAAS,SAAS;CAC/C,IAAI,WAAW;CACf,OAAO;EACL;EACA,QAAQ,WAAW;GACjB,IAAI,UAAU;GACd,WAAW;GACX,EAAE,OAAO,EAAE;EACb;CACF;AACF;AACA,SAAS,WAAW,MAAM,UAAU,cAAc,QAAQ;CACxD,IAAI,QAAQ,IAAI,MAAM,KAAK,MAAM;CACjC,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;EACpC,MAAM,KAAK,cAAc,KAAK,EAAE;CAClC;CACA,UAAU,CAAC,CAAC,WAAW,OAAO,UAAU,cAAc,MAAM;AAC9D;AACA,SAAS,OAAO,IAAI;CAClB,UAAU,CAAC,CAAC,OAAO,EAAE;AACvB;AACA,SAAS,gBAAgB,SAAS;CAChC,IAAI,QAAQ,WAAW,GAAG;CAC1B,UAAU,CAAC,CAAC,gBAAgB,OAAO;AACrC;AACA,SAAS,cAAc,SAAS,OAAO,OAAO;CAC5C,UAAU,CAAC,CAAC,cAAc,SAAS,OAAO,KAAK;AACjD;AACA,SAAS,aAAa,WAAW;CAC/B,IAAI,UAAU,UAAU,SAAS,KAAK,UAAU,OAAO,KAAK,IAAI,UAAU,KAAK,cAAc;CAC7F,CAAC,GAAG,cAAc,qBAAoB,CAAE,SAAS,SAAS;CAC1D,UAAU,CAAC,CAAC,aAAa,SAAS,SAAS;AAC7C;AACA,SAAS,YAAY,SAAS;CAC5B,CAAC,GAAG,cAAc,oBAAmB,CAAE,OAAO;CAC9C,UAAU,CAAC,CAAC,YAAY,OAAO;AACjC;AACA,SAAS,aAAa,OAAO;CAC3B,IAAI,UAAU,UAAU,SAAS,KAAK,UAAU,OAAO,KAAK,IAAI,UAAU,KAAK,cAAc;CAC7F,IAAI;CACJ,IAAI,QAAQ,GAAG,cAAc,qBAAoB,CAAE,OAAO;CAC1D,OAAO;EACL,GAAG,MAAM;EACT,GAAG,QAAQ,eAAe,MAAM,WAAW,QAAQ,iBAAiB,KAAK,IAAI,KAAK,IAAI,aAAa,QAAQ,KAAK;CAClH;AACF;AACA,SAAS,aAAa,IAAI;CACxB,IAAI,CAAC,QAAQ,OAAO;CACpB,OAAO,OAAO,aAAa,EAAE;AAC/B;AACA,SAAS,WAAW;CAClB,IAAI,CAAC,QAAQ,OAAO;EAClB,WAAW;EACX,aAAa;EACb,WAAW;CACb;CACA,OAAO;EACL,WAAW,OAAO,aAAa;EAC/B,aAAa,OAAO,eAAe;EACnC,WAAW,OAAO,aAAa;CACjC;AACF"}
package/dist/esm/index.js CHANGED
@@ -6,9 +6,7 @@ function isAvailable() {
6
6
  function link(_ref, _table, _scopeId, _commitNow) {
7
7
  return null;
8
8
  }
9
- function linkTables(_refs, _tableIds, _scopeIndexes, _scopes) {
10
- return 0;
11
- }
9
+ function linkTables(_refs, _tableIds, _scopeIndexes, _scopes) {}
12
10
  function unlink(_id) {}
13
11
  function applyViewStates(_entries) {}
14
12
  function setTableState(_tableId, _state, _props) {}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["esm/index.js"],"sourcesContent":["import {\n ROOT_SCOPE,\n getMirroredStateName,\n removeMirroredScope,\n setMirroredStateName\n} from \"./mirror\";\nimport { ROOT_SCOPE as ROOT_SCOPE2, getMirroredStateName as getMirroredStateName2 } from \"./mirror\";\nfunction isAvailable() {\n return false;\n}\nfunction link(_ref, _table, _scopeId, _commitNow) {\n return null;\n}\nfunction linkTables(_refs, _tableIds, _scopeIndexes, _scopes) {\n return 0;\n}\nfunction unlink(_id) {\n}\nfunction applyViewStates(_entries) {\n}\nfunction setTableState(_tableId, _state, _props) {\n}\nfunction getViewState(_id) {\n return null;\n}\nfunction setStateName(stateName, scopeId = ROOT_SCOPE) {\n setMirroredStateName(scopeId, stateName);\n}\nfunction removeScope(scopeId) {\n removeMirroredScope(scopeId);\n}\nfunction resolveSlots(slots, scopeId = ROOT_SCOPE) {\n const name = getMirroredStateName(scopeId);\n return {\n ...slots.base,\n ...name ? slots.state?.[name] : void 0\n };\n}\nfunction getStats() {\n return { viewCount: 0, commitCount: 0, missCount: 0 };\n}\nfunction processStyleColors(props) {\n return props;\n}\nexport {\n ROOT_SCOPE2 as ROOT_SCOPE,\n applyViewStates,\n getMirroredStateName2 as getMirroredStateName,\n getStats,\n getViewState,\n isAvailable,\n link,\n linkTables,\n processStyleColors,\n removeScope,\n resolveSlots,\n setStateName,\n setTableState,\n unlink\n};\n//# sourceMappingURL=index.js.map\n"],"mappings":";;;AAOA,SAAS,cAAc;CACrB,OAAO;AACT;AACA,SAAS,KAAK,MAAM,QAAQ,UAAU,YAAY;CAChD,OAAO;AACT;AACA,SAAS,WAAW,OAAO,WAAW,eAAe,SAAS;CAC5D,OAAO;AACT;AACA,SAAS,OAAO,KAAK,CACrB;AACA,SAAS,gBAAgB,UAAU,CACnC;AACA,SAAS,cAAc,UAAU,QAAQ,QAAQ,CACjD;AACA,SAAS,aAAa,KAAK;CACzB,OAAO;AACT;AACA,SAAS,aAAa,WAAW,UAAU,YAAY;CACrD,qBAAqB,SAAS,SAAS;AACzC;AACA,SAAS,YAAY,SAAS;CAC5B,oBAAoB,OAAO;AAC7B;AACA,SAAS,aAAa,OAAO,UAAU,YAAY;CACjD,MAAM,OAAO,qBAAqB,OAAO;CACzC,OAAO;EACL,GAAG,MAAM;EACT,GAAG,OAAO,MAAM,QAAQ,QAAQ,KAAK;CACvC;AACF;AACA,SAAS,WAAW;CAClB,OAAO;EAAE,WAAW;EAAG,aAAa;EAAG,WAAW;CAAE;AACtD;AACA,SAAS,mBAAmB,OAAO;CACjC,OAAO;AACT"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["esm/index.js"],"sourcesContent":["import {\n ROOT_SCOPE,\n getMirroredStateName,\n removeMirroredScope,\n setMirroredStateName\n} from \"./mirror\";\nimport { ROOT_SCOPE as ROOT_SCOPE2, getMirroredStateName as getMirroredStateName2 } from \"./mirror\";\nfunction isAvailable() {\n return false;\n}\nfunction link(_ref, _table, _scopeId, _commitNow) {\n return null;\n}\nfunction linkTables(_refs, _tableIds, _scopeIndexes, _scopes) {\n}\nfunction unlink(_id) {\n}\nfunction applyViewStates(_entries) {\n}\nfunction setTableState(_tableId, _state, _props) {\n}\nfunction getViewState(_id) {\n return null;\n}\nfunction setStateName(stateName, scopeId = ROOT_SCOPE) {\n setMirroredStateName(scopeId, stateName);\n}\nfunction removeScope(scopeId) {\n removeMirroredScope(scopeId);\n}\nfunction resolveSlots(slots, scopeId = ROOT_SCOPE) {\n const name = getMirroredStateName(scopeId);\n return {\n ...slots.base,\n ...name ? slots.state?.[name] : void 0\n };\n}\nfunction getStats() {\n return { viewCount: 0, commitCount: 0, missCount: 0 };\n}\nfunction processStyleColors(props) {\n return props;\n}\nexport {\n ROOT_SCOPE2 as ROOT_SCOPE,\n applyViewStates,\n getMirroredStateName2 as getMirroredStateName,\n getStats,\n getViewState,\n isAvailable,\n link,\n linkTables,\n processStyleColors,\n removeScope,\n resolveSlots,\n setStateName,\n setTableState,\n unlink\n};\n//# sourceMappingURL=index.js.map\n"],"mappings":";;;AAOA,SAAS,cAAc;CACrB,OAAO;AACT;AACA,SAAS,KAAK,MAAM,QAAQ,UAAU,YAAY;CAChD,OAAO;AACT;AACA,SAAS,WAAW,OAAO,WAAW,eAAe,SAAS,CAC9D;AACA,SAAS,OAAO,KAAK,CACrB;AACA,SAAS,gBAAgB,UAAU,CACnC;AACA,SAAS,cAAc,UAAU,QAAQ,QAAQ,CACjD;AACA,SAAS,aAAa,KAAK;CACzB,OAAO;AACT;AACA,SAAS,aAAa,WAAW,UAAU,YAAY;CACrD,qBAAqB,SAAS,SAAS;AACzC;AACA,SAAS,YAAY,SAAS;CAC5B,oBAAoB,OAAO;AAC7B;AACA,SAAS,aAAa,OAAO,UAAU,YAAY;CACjD,MAAM,OAAO,qBAAqB,OAAO;CACzC,OAAO;EACL,GAAG,MAAM;EACT,GAAG,OAAO,MAAM,QAAQ,QAAQ,KAAK;CACvC;AACF;AACA,SAAS,WAAW;CAClB,OAAO;EAAE,WAAW;EAAG,aAAa;EAAG,WAAW;CAAE;AACtD;AACA,SAAS,mBAAmB,OAAO;CACjC,OAAO;AACT"}
@@ -6,9 +6,7 @@ function isAvailable() {
6
6
  function link(_ref, _table, _scopeId, _commitNow) {
7
7
  return null;
8
8
  }
9
- function linkTables(_refs, _tableIds, _scopeIndexes, _scopes) {
10
- return 0;
11
- }
9
+ function linkTables(_refs, _tableIds, _scopeIndexes, _scopes) {}
12
10
  function unlink(_id) {}
13
11
  function applyViewStates(_entries) {}
14
12
  function setTableState(_tableId, _state, _props) {}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["esm/index.js"],"sourcesContent":["import {\n ROOT_SCOPE,\n getMirroredStateName,\n removeMirroredScope,\n setMirroredStateName\n} from \"./mirror\";\nimport { ROOT_SCOPE as ROOT_SCOPE2, getMirroredStateName as getMirroredStateName2 } from \"./mirror\";\nfunction isAvailable() {\n return false;\n}\nfunction link(_ref, _table, _scopeId, _commitNow) {\n return null;\n}\nfunction linkTables(_refs, _tableIds, _scopeIndexes, _scopes) {\n return 0;\n}\nfunction unlink(_id) {\n}\nfunction applyViewStates(_entries) {\n}\nfunction setTableState(_tableId, _state, _props) {\n}\nfunction getViewState(_id) {\n return null;\n}\nfunction setStateName(stateName, scopeId = ROOT_SCOPE) {\n setMirroredStateName(scopeId, stateName);\n}\nfunction removeScope(scopeId) {\n removeMirroredScope(scopeId);\n}\nfunction resolveSlots(slots, scopeId = ROOT_SCOPE) {\n const name = getMirroredStateName(scopeId);\n return {\n ...slots.base,\n ...name ? slots.state?.[name] : void 0\n };\n}\nfunction getStats() {\n return { viewCount: 0, commitCount: 0, missCount: 0 };\n}\nfunction processStyleColors(props) {\n return props;\n}\nexport {\n ROOT_SCOPE2 as ROOT_SCOPE,\n applyViewStates,\n getMirroredStateName2 as getMirroredStateName,\n getStats,\n getViewState,\n isAvailable,\n link,\n linkTables,\n processStyleColors,\n removeScope,\n resolveSlots,\n setStateName,\n setTableState,\n unlink\n};\n//# sourceMappingURL=index.js.map\n"],"mappings":";;;AAOA,SAAS,cAAc;CACrB,OAAO;AACT;AACA,SAAS,KAAK,MAAM,QAAQ,UAAU,YAAY;CAChD,OAAO;AACT;AACA,SAAS,WAAW,OAAO,WAAW,eAAe,SAAS;CAC5D,OAAO;AACT;AACA,SAAS,OAAO,KAAK,CACrB;AACA,SAAS,gBAAgB,UAAU,CACnC;AACA,SAAS,cAAc,UAAU,QAAQ,QAAQ,CACjD;AACA,SAAS,aAAa,KAAK;CACzB,OAAO;AACT;AACA,SAAS,aAAa,WAAW,UAAU,YAAY;CACrD,qBAAqB,SAAS,SAAS;AACzC;AACA,SAAS,YAAY,SAAS;CAC5B,oBAAoB,OAAO;AAC7B;AACA,SAAS,aAAa,OAAO,UAAU,YAAY;CACjD,MAAM,OAAO,qBAAqB,OAAO;CACzC,OAAO;EACL,GAAG,MAAM;EACT,GAAG,OAAO,MAAM,QAAQ,QAAQ,KAAK;CACvC;AACF;AACA,SAAS,WAAW;CAClB,OAAO;EAAE,WAAW;EAAG,aAAa;EAAG,WAAW;CAAE;AACtD;AACA,SAAS,mBAAmB,OAAO;CACjC,OAAO;AACT"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["esm/index.js"],"sourcesContent":["import {\n ROOT_SCOPE,\n getMirroredStateName,\n removeMirroredScope,\n setMirroredStateName\n} from \"./mirror\";\nimport { ROOT_SCOPE as ROOT_SCOPE2, getMirroredStateName as getMirroredStateName2 } from \"./mirror\";\nfunction isAvailable() {\n return false;\n}\nfunction link(_ref, _table, _scopeId, _commitNow) {\n return null;\n}\nfunction linkTables(_refs, _tableIds, _scopeIndexes, _scopes) {\n}\nfunction unlink(_id) {\n}\nfunction applyViewStates(_entries) {\n}\nfunction setTableState(_tableId, _state, _props) {\n}\nfunction getViewState(_id) {\n return null;\n}\nfunction setStateName(stateName, scopeId = ROOT_SCOPE) {\n setMirroredStateName(scopeId, stateName);\n}\nfunction removeScope(scopeId) {\n removeMirroredScope(scopeId);\n}\nfunction resolveSlots(slots, scopeId = ROOT_SCOPE) {\n const name = getMirroredStateName(scopeId);\n return {\n ...slots.base,\n ...name ? slots.state?.[name] : void 0\n };\n}\nfunction getStats() {\n return { viewCount: 0, commitCount: 0, missCount: 0 };\n}\nfunction processStyleColors(props) {\n return props;\n}\nexport {\n ROOT_SCOPE2 as ROOT_SCOPE,\n applyViewStates,\n getMirroredStateName2 as getMirroredStateName,\n getStats,\n getViewState,\n isAvailable,\n link,\n linkTables,\n processStyleColors,\n removeScope,\n resolveSlots,\n setStateName,\n setTableState,\n unlink\n};\n//# sourceMappingURL=index.js.map\n"],"mappings":";;;AAOA,SAAS,cAAc;CACrB,OAAO;AACT;AACA,SAAS,KAAK,MAAM,QAAQ,UAAU,YAAY;CAChD,OAAO;AACT;AACA,SAAS,WAAW,OAAO,WAAW,eAAe,SAAS,CAC9D;AACA,SAAS,OAAO,KAAK,CACrB;AACA,SAAS,gBAAgB,UAAU,CACnC;AACA,SAAS,cAAc,UAAU,QAAQ,QAAQ,CACjD;AACA,SAAS,aAAa,KAAK;CACzB,OAAO;AACT;AACA,SAAS,aAAa,WAAW,UAAU,YAAY;CACrD,qBAAqB,SAAS,SAAS;AACzC;AACA,SAAS,YAAY,SAAS;CAC5B,oBAAoB,OAAO;AAC7B;AACA,SAAS,aAAa,OAAO,UAAU,YAAY;CACjD,MAAM,OAAO,qBAAqB,OAAO;CACzC,OAAO;EACL,GAAG,MAAM;EACT,GAAG,OAAO,MAAM,QAAQ,QAAQ,KAAK;CACvC;AACF;AACA,SAAS,WAAW;CAClB,OAAO;EAAE,WAAW;EAAG,aAAa;EAAG,WAAW;CAAE;AACtD;AACA,SAAS,mBAAmB,OAAO;CACjC,OAAO;AACT"}
@@ -49,7 +49,7 @@ function linkTables(refs, tableIds, scopeIndexes, scopes) {
49
49
  for (var i = 0; i < refs.length; i++) {
50
50
  nodes[i] = getShadowNode(refs[i]);
51
51
  }
52
- return getEngine().linkTables(nodes, tableIds, scopeIndexes, scopes);
52
+ getEngine().linkTables(nodes, tableIds, scopeIndexes, scopes);
53
53
  }
54
54
  function unlink(id) {
55
55
  getEngine().unlink(id);
@@ -1 +1 @@
1
- {"version":3,"file":"index.native.js","names":[],"sources":["esm/index.native.js"],"sourcesContent":["import { NitroModules } from \"react-native-nitro-modules\";\nimport { ROOT_SCOPE, getMirroredStateName, removeMirroredScope, setMirroredStateName } from \"./mirror\";\nimport { ROOT_SCOPE as ROOT_SCOPE2, getMirroredStateName as getMirroredStateName2 } from \"./mirror\";\nimport { processStyleColors } from \"./processStyleColors.native\";\nvar engine = null;\nvar initError = null;\ntry {\n engine = NitroModules.createHybridObject(\"TamaguiRegistry\");\n} catch (error) {\n initError = error;\n}\nfunction isAvailable() {\n return engine !== null;\n}\nfunction getEngine() {\n if (engine) return engine;\n var detail = initError instanceof Error ? ` ${initError.message}` : \"\";\n throw new Error(`[@tamagui/native-registry] TamaguiRegistry failed to initialize; is react-native-nitro-modules installed and the app rebuilt?${detail}`);\n}\nfunction getShadowNode(ref) {\n var _handle_stateNode;\n var handle = ref === null || ref === void 0 ? void 0 : ref.__internalInstanceHandle;\n var _handle_stateNode_node;\n return (_handle_stateNode_node = handle === null || handle === void 0 ? void 0 : (_handle_stateNode = handle.stateNode) === null || _handle_stateNode === void 0 ? void 0 : _handle_stateNode.node) !== null && _handle_stateNode_node !== void 0 ? _handle_stateNode_node : null;\n}\nfunction isNitroHybridView(ref) {\n var config = ref === null || ref === void 0 ? void 0 : ref.__viewConfig;\n return !!(config === null || config === void 0 ? void 0 : config.validAttributes) && \"hybridRef\" in config.validAttributes;\n}\nfunction link(ref, table) {\n var scopeId = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : ROOT_SCOPE, commitNow = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : false;\n if (isNitroHybridView(ref)) return null;\n var node = getShadowNode(ref);\n if (!node) return null;\n var e = getEngine();\n var id = e.link(node, table, scopeId, commitNow);\n var unlinked = false;\n return {\n id,\n unlink: function() {\n if (unlinked) return;\n unlinked = true;\n e.unlink(id);\n }\n };\n}\nfunction linkTables(refs, tableIds, scopeIndexes, scopes) {\n var nodes = new Array(refs.length);\n for (var i = 0; i < refs.length; i++) {\n nodes[i] = getShadowNode(refs[i]);\n }\n return getEngine().linkTables(nodes, tableIds, scopeIndexes, scopes);\n}\nfunction unlink(id) {\n getEngine().unlink(id);\n}\nfunction applyViewStates(entries) {\n if (entries.length === 0) return;\n getEngine().applyViewStates(entries);\n}\nfunction setTableState(tableId, state, props) {\n getEngine().setTableState(tableId, state, props);\n}\nfunction setStateName(stateName) {\n var scopeId = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : ROOT_SCOPE;\n setMirroredStateName(scopeId, stateName);\n getEngine().setStateName(scopeId, stateName);\n}\nfunction removeScope(scopeId) {\n removeMirroredScope(scopeId);\n getEngine().removeScope(scopeId);\n}\nfunction resolveSlots(slots) {\n var scopeId = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : ROOT_SCOPE;\n var _slots_state;\n var name = getMirroredStateName(scopeId);\n return {\n ...slots.base,\n ...name ? (_slots_state = slots.state) === null || _slots_state === void 0 ? void 0 : _slots_state[name] : void 0\n };\n}\nfunction getViewState(id) {\n if (!engine) return null;\n return engine.getViewState(id);\n}\nfunction getStats() {\n if (!engine) return {\n viewCount: 0,\n commitCount: 0,\n missCount: 0\n };\n return {\n viewCount: engine.getViewCount(),\n commitCount: engine.getCommitCount(),\n missCount: engine.getMissCount()\n };\n}\nexport {\n ROOT_SCOPE2 as ROOT_SCOPE,\n applyViewStates,\n getMirroredStateName2 as getMirroredStateName,\n getStats,\n getViewState,\n isAvailable,\n link,\n linkTables,\n processStyleColors,\n removeScope,\n resolveSlots,\n setStateName,\n setTableState,\n unlink\n};\n//# sourceMappingURL=index.native.js.map\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.native.js","names":[],"sources":["esm/index.native.js"],"sourcesContent":["import { NitroModules } from \"react-native-nitro-modules\";\nimport { ROOT_SCOPE, getMirroredStateName, removeMirroredScope, setMirroredStateName } from \"./mirror\";\nimport { ROOT_SCOPE as ROOT_SCOPE2, getMirroredStateName as getMirroredStateName2 } from \"./mirror\";\nimport { processStyleColors } from \"./processStyleColors.native\";\nvar engine = null;\nvar initError = null;\ntry {\n engine = NitroModules.createHybridObject(\"TamaguiRegistry\");\n} catch (error) {\n initError = error;\n}\nfunction isAvailable() {\n return engine !== null;\n}\nfunction getEngine() {\n if (engine) return engine;\n var detail = initError instanceof Error ? ` ${initError.message}` : \"\";\n throw new Error(`[@tamagui/native-registry] TamaguiRegistry failed to initialize; is react-native-nitro-modules installed and the app rebuilt?${detail}`);\n}\nfunction getShadowNode(ref) {\n var _handle_stateNode;\n var handle = ref === null || ref === void 0 ? void 0 : ref.__internalInstanceHandle;\n var _handle_stateNode_node;\n return (_handle_stateNode_node = handle === null || handle === void 0 ? void 0 : (_handle_stateNode = handle.stateNode) === null || _handle_stateNode === void 0 ? void 0 : _handle_stateNode.node) !== null && _handle_stateNode_node !== void 0 ? _handle_stateNode_node : null;\n}\nfunction isNitroHybridView(ref) {\n var config = ref === null || ref === void 0 ? void 0 : ref.__viewConfig;\n return !!(config === null || config === void 0 ? void 0 : config.validAttributes) && \"hybridRef\" in config.validAttributes;\n}\nfunction link(ref, table) {\n var scopeId = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : ROOT_SCOPE, commitNow = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : false;\n if (isNitroHybridView(ref)) return null;\n var node = getShadowNode(ref);\n if (!node) return null;\n var e = getEngine();\n var id = e.link(node, table, scopeId, commitNow);\n var unlinked = false;\n return {\n id,\n unlink: function() {\n if (unlinked) return;\n unlinked = true;\n e.unlink(id);\n }\n };\n}\nfunction linkTables(refs, tableIds, scopeIndexes, scopes) {\n var nodes = new Array(refs.length);\n for (var i = 0; i < refs.length; i++) {\n nodes[i] = getShadowNode(refs[i]);\n }\n getEngine().linkTables(nodes, tableIds, scopeIndexes, scopes);\n}\nfunction unlink(id) {\n getEngine().unlink(id);\n}\nfunction applyViewStates(entries) {\n if (entries.length === 0) return;\n getEngine().applyViewStates(entries);\n}\nfunction setTableState(tableId, state, props) {\n getEngine().setTableState(tableId, state, props);\n}\nfunction setStateName(stateName) {\n var scopeId = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : ROOT_SCOPE;\n setMirroredStateName(scopeId, stateName);\n getEngine().setStateName(scopeId, stateName);\n}\nfunction removeScope(scopeId) {\n removeMirroredScope(scopeId);\n getEngine().removeScope(scopeId);\n}\nfunction resolveSlots(slots) {\n var scopeId = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : ROOT_SCOPE;\n var _slots_state;\n var name = getMirroredStateName(scopeId);\n return {\n ...slots.base,\n ...name ? (_slots_state = slots.state) === null || _slots_state === void 0 ? void 0 : _slots_state[name] : void 0\n };\n}\nfunction getViewState(id) {\n if (!engine) return null;\n return engine.getViewState(id);\n}\nfunction getStats() {\n if (!engine) return {\n viewCount: 0,\n commitCount: 0,\n missCount: 0\n };\n return {\n viewCount: engine.getViewCount(),\n commitCount: engine.getCommitCount(),\n missCount: engine.getMissCount()\n };\n}\nexport {\n ROOT_SCOPE2 as ROOT_SCOPE,\n applyViewStates,\n getMirroredStateName2 as getMirroredStateName,\n getStats,\n getViewState,\n isAvailable,\n link,\n linkTables,\n processStyleColors,\n removeScope,\n resolveSlots,\n setStateName,\n setTableState,\n unlink\n};\n//# sourceMappingURL=index.native.js.map\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tamagui/native-registry",
3
- "version": "3.0.5",
3
+ "version": "3.0.6",
4
4
  "description": "Generic native style registry: zero-re-render style updates via Fabric ShadowTree commits",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -46,7 +46,7 @@
46
46
  }
47
47
  },
48
48
  "devDependencies": {
49
- "@tamagui/build": "3.0.5",
49
+ "@tamagui/build": "3.0.6",
50
50
  "react": "19.2.3",
51
51
  "react-native": "0.87.1",
52
52
  "react-native-nitro-modules": "0.37.1",
@@ -77,5 +77,5 @@
77
77
  "publishConfig": {
78
78
  "access": "public"
79
79
  },
80
- "releaseSourceCommit": "2500e65729dfd41ce27b4b3271f22f9c1d1ff5a3"
80
+ "releaseSourceCommit": "ee01c1a5d113f9d0f4e9e26c35154165ce25add6"
81
81
  }
@@ -44,7 +44,7 @@ interface Engine extends TamaguiRegistry {
44
44
  tableIds: number[],
45
45
  scopeIndexes: number[],
46
46
  scopes: string[]
47
- ): number
47
+ ): void
48
48
  applyViewStates(entries: ViewStateUpdate[]): void
49
49
  setTableState(tableId: number, state: string, props: Record<string, unknown>): void
50
50
  getViewState(id: number): ViewStateSnapshot | null
@@ -129,25 +129,25 @@ export function link(
129
129
 
130
130
  /**
131
131
  * Link many host views to shared tables in one native call. Entry i links
132
- * refs[i] to table tableIds[i] under scope scopes[scopeIndexes[i]]. Returns
133
- * the id of entry 0; ids are consecutive, and an entry whose host has no
134
- * shadow node consumes its id unlinked. The refs are React Native host
135
- * components (never Nitro views, see link).
132
+ * refs[i] to table tableIds[i] under scope scopes[scopeIndexes[i]]. A host
133
+ * already linked to a table moves to its new entry, and the engine drops
134
+ * linked views that left the tree, so table links need no unlink. The refs
135
+ * are React Native host components (never Nitro views, see link).
136
136
  */
137
137
  export function linkTables(
138
138
  refs: unknown[],
139
139
  tableIds: number[],
140
140
  scopeIndexes: number[],
141
141
  scopes: string[]
142
- ): number {
142
+ ): void {
143
143
  const nodes = new Array(refs.length)
144
144
  for (let i = 0; i < refs.length; i++) {
145
145
  nodes[i] = getShadowNode(refs[i])
146
146
  }
147
- return getEngine().linkTables(nodes, tableIds, scopeIndexes, scopes)
147
+ getEngine().linkTables(nodes, tableIds, scopeIndexes, scopes)
148
148
  }
149
149
 
150
- /** Unlink by an id from linkTables. Safe to call twice. */
150
+ /** Unlink by an id from link. Safe to call twice. */
151
151
  export function unlink(id: number): void {
152
152
  getEngine().unlink(id)
153
153
  }
package/src/index.ts CHANGED
@@ -45,9 +45,7 @@ export function linkTables(
45
45
  _tableIds: number[],
46
46
  _scopeIndexes: number[],
47
47
  _scopes: string[]
48
- ): number {
49
- return 0
50
- }
48
+ ): void {}
51
49
 
52
50
  export function unlink(_id: number): void {}
53
51
 
package/types/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export type { LinkHandle, RegistryStats, Unlink, ViewSlots, ViewStateSnapshot, V
8
8
  export { ROOT_SCOPE, getMirroredStateName } from "./mirror";
9
9
  export declare function isAvailable(): boolean;
10
10
  export declare function link(_ref: unknown, _table: ViewSlots | number, _scopeId?: string, _commitNow?: boolean): LinkHandle | null;
11
- export declare function linkTables(_refs: unknown[], _tableIds: number[], _scopeIndexes: number[], _scopes: string[]): number;
11
+ export declare function linkTables(_refs: unknown[], _tableIds: number[], _scopeIndexes: number[], _scopes: string[]): void;
12
12
  export declare function unlink(_id: number): void;
13
13
  export declare function applyViewStates(_entries: ViewStateUpdate[]): void;
14
14
  export declare function setTableState(_tableId: number, _state: string, _props: Record<string, unknown>): void;
@@ -1,11 +1,11 @@
1
1
  {
2
- "mappings": ";;;;;AAKA,cACE,YACA,eACA,WACA,mBACA,uBACK;AAQP,cACE,YACA,eACA,QACA,WACA,mBACA,uBACK;AACP,SAAS,YAAY,4BAA4B;AAEjD,OAAO,iBAAS;AAIhB,OAAO,iBAAS,KACd,eACA,QAAQ,oBACR,mBACA,uBACC;AAIH,OAAO,iBAAS,WACd,kBACA,qBACA,yBACA;AAKF,OAAO,iBAAS,OAAO;AAEvB,OAAO,iBAAS,gBAAgB,UAAU;AAE1C,OAAO,iBAAS,cACd,kBACA,gBACA,QAAQ;AAGV,OAAO,iBAAS,aAAa,cAAc;AAI3C,OAAO,iBAAS,aAAa,mBAAmB;AAIhD,OAAO,iBAAS,YAAY;AAI5B,OAAO,iBAAS,aACd,OAAO,WACP,mBACC;AAQH,OAAO,iBAAS,YAAY;AAI5B,OAAO,iBAAS,mBACd,OAAO,0BACN",
2
+ "mappings": ";;;;;AAKA,cACE,YACA,eACA,WACA,mBACA,uBACK;AAQP,cACE,YACA,eACA,QACA,WACA,mBACA,uBACK;AACP,SAAS,YAAY,4BAA4B;AAEjD,OAAO,iBAAS;AAIhB,OAAO,iBAAS,KACd,eACA,QAAQ,oBACR,mBACA,uBACC;AAIH,OAAO,iBAAS,WACd,kBACA,qBACA,yBACA;AAGF,OAAO,iBAAS,OAAO;AAEvB,OAAO,iBAAS,gBAAgB,UAAU;AAE1C,OAAO,iBAAS,cACd,kBACA,gBACA,QAAQ;AAGV,OAAO,iBAAS,aAAa,cAAc;AAI3C,OAAO,iBAAS,aAAa,mBAAmB;AAIhD,OAAO,iBAAS,YAAY;AAI5B,OAAO,iBAAS,aACd,OAAO,WACP,mBACC;AAQH,OAAO,iBAAS,YAAY;AAI5B,OAAO,iBAAS,mBACd,OAAO,0BACN",
3
3
  "names": [],
4
4
  "sources": [
5
5
  "src/index.ts"
6
6
  ],
7
7
  "version": 3,
8
8
  "sourcesContent": [
9
- "/**\n * Web/no-native fallback. The registry is a native-only optimization; on web\n * (or when the native module is absent) the mirror still tracks scope state\n * so shared code can resolve slots, but nothing links and nothing commits.\n */\nimport type {\n LinkHandle,\n RegistryStats,\n ViewSlots,\n ViewStateSnapshot,\n ViewStateUpdate,\n} from './types'\nimport {\n ROOT_SCOPE,\n getMirroredStateName,\n removeMirroredScope,\n setMirroredStateName,\n} from './mirror'\n\nexport type {\n LinkHandle,\n RegistryStats,\n Unlink,\n ViewSlots,\n ViewStateSnapshot,\n ViewStateUpdate,\n} from './types'\nexport { ROOT_SCOPE, getMirroredStateName } from './mirror'\n\nexport function isAvailable(): boolean {\n return false\n}\n\nexport function link(\n _ref: unknown,\n _table: ViewSlots | number,\n _scopeId?: string,\n _commitNow?: boolean\n): LinkHandle | null {\n return null\n}\n\nexport function linkTables(\n _refs: unknown[],\n _tableIds: number[],\n _scopeIndexes: number[],\n _scopes: string[]\n): number {\n return 0\n}\n\nexport function unlink(_id: number): void {}\n\nexport function applyViewStates(_entries: ViewStateUpdate[]): void {}\n\nexport function setTableState(\n _tableId: number,\n _state: string,\n _props: Record<string, unknown>\n): void {}\n\nexport function getViewState(_id: number): ViewStateSnapshot | null {\n return null\n}\n\nexport function setStateName(stateName: string, scopeId: string = ROOT_SCOPE): void {\n setMirroredStateName(scopeId, stateName)\n}\n\nexport function removeScope(scopeId: string): void {\n removeMirroredScope(scopeId)\n}\n\nexport function resolveSlots(\n slots: ViewSlots,\n scopeId: string = ROOT_SCOPE\n): Record<string, unknown> {\n const name = getMirroredStateName(scopeId)\n return {\n ...slots.base,\n ...(name ? slots.state?.[name] : undefined),\n }\n}\n\nexport function getStats(): RegistryStats {\n return { viewCount: 0, commitCount: 0, missCount: 0 }\n}\n\nexport function processStyleColors(\n props: Record<string, unknown>\n): Record<string, unknown> {\n return props\n}\n"
9
+ "/**\n * Web/no-native fallback. The registry is a native-only optimization; on web\n * (or when the native module is absent) the mirror still tracks scope state\n * so shared code can resolve slots, but nothing links and nothing commits.\n */\nimport type {\n LinkHandle,\n RegistryStats,\n ViewSlots,\n ViewStateSnapshot,\n ViewStateUpdate,\n} from './types'\nimport {\n ROOT_SCOPE,\n getMirroredStateName,\n removeMirroredScope,\n setMirroredStateName,\n} from './mirror'\n\nexport type {\n LinkHandle,\n RegistryStats,\n Unlink,\n ViewSlots,\n ViewStateSnapshot,\n ViewStateUpdate,\n} from './types'\nexport { ROOT_SCOPE, getMirroredStateName } from './mirror'\n\nexport function isAvailable(): boolean {\n return false\n}\n\nexport function link(\n _ref: unknown,\n _table: ViewSlots | number,\n _scopeId?: string,\n _commitNow?: boolean\n): LinkHandle | null {\n return null\n}\n\nexport function linkTables(\n _refs: unknown[],\n _tableIds: number[],\n _scopeIndexes: number[],\n _scopes: string[]\n): void {}\n\nexport function unlink(_id: number): void {}\n\nexport function applyViewStates(_entries: ViewStateUpdate[]): void {}\n\nexport function setTableState(\n _tableId: number,\n _state: string,\n _props: Record<string, unknown>\n): void {}\n\nexport function getViewState(_id: number): ViewStateSnapshot | null {\n return null\n}\n\nexport function setStateName(stateName: string, scopeId: string = ROOT_SCOPE): void {\n setMirroredStateName(scopeId, stateName)\n}\n\nexport function removeScope(scopeId: string): void {\n removeMirroredScope(scopeId)\n}\n\nexport function resolveSlots(\n slots: ViewSlots,\n scopeId: string = ROOT_SCOPE\n): Record<string, unknown> {\n const name = getMirroredStateName(scopeId)\n return {\n ...slots.base,\n ...(name ? slots.state?.[name] : undefined),\n }\n}\n\nexport function getStats(): RegistryStats {\n return { viewCount: 0, commitCount: 0, missCount: 0 }\n}\n\nexport function processStyleColors(\n props: Record<string, unknown>\n): Record<string, unknown> {\n return props\n}\n"
10
10
  ]
11
11
  }
@@ -17,13 +17,13 @@ export declare function isAvailable(): boolean;
17
17
  export declare function link(ref: unknown, table: ViewSlots | number, scopeId?: string, commitNow?: boolean): LinkHandle | null;
18
18
  /**
19
19
  * Link many host views to shared tables in one native call. Entry i links
20
- * refs[i] to table tableIds[i] under scope scopes[scopeIndexes[i]]. Returns
21
- * the id of entry 0; ids are consecutive, and an entry whose host has no
22
- * shadow node consumes its id unlinked. The refs are React Native host
23
- * components (never Nitro views, see link).
20
+ * refs[i] to table tableIds[i] under scope scopes[scopeIndexes[i]]. A host
21
+ * already linked to a table moves to its new entry, and the engine drops
22
+ * linked views that left the tree, so table links need no unlink. The refs
23
+ * are React Native host components (never Nitro views, see link).
24
24
  */
25
- export declare function linkTables(refs: unknown[], tableIds: number[], scopeIndexes: number[], scopes: string[]): number;
26
- /** Unlink by an id from linkTables. Safe to call twice. */
25
+ export declare function linkTables(refs: unknown[], tableIds: number[], scopeIndexes: number[], scopes: string[]): void;
26
+ /** Unlink by an id from link. Safe to call twice. */
27
27
  export declare function unlink(id: number): void;
28
28
  /**
29
29
  * Batched per-view state selection: cold entries carry `props` (computed by
@@ -6,6 +6,6 @@
6
6
  ],
7
7
  "version": 3,
8
8
  "sourcesContent": [
9
- "/**\n * Native implementation backed by the TamaguiRegistry Nitro HybridObject.\n * The C++ engine commits style updates directly to Fabric's ShadowTree via\n * UIManager::updateShadowTree (RN >= 0.81), with zero React re-renders.\n */\nimport { NitroModules } from 'react-native-nitro-modules'\nimport type { TamaguiRegistry } from './specs/TamaguiRegistry.nitro'\nimport type {\n LinkHandle,\n RegistryStats,\n Unlink,\n ViewSlots,\n ViewStateSnapshot,\n ViewStateUpdate,\n} from './types'\nimport {\n ROOT_SCOPE,\n getMirroredStateName,\n removeMirroredScope,\n setMirroredStateName,\n} from './mirror'\n\nexport type {\n LinkHandle,\n RegistryStats,\n Unlink,\n ViewSlots,\n ViewStateSnapshot,\n ViewStateUpdate,\n} from './types'\nexport { ROOT_SCOPE, getMirroredStateName } from './mirror'\nexport { processStyleColors } from './processStyleColors.native'\n\n/** Full engine surface: typed Nitro methods plus the raw-JSI methods. */\ninterface Engine extends TamaguiRegistry {\n link(\n shadowNode: unknown,\n table: ViewSlots | number,\n scopeId: string,\n commitNow: boolean\n ): number\n linkTables(\n shadowNodes: unknown[],\n tableIds: number[],\n scopeIndexes: number[],\n scopes: string[]\n ): number\n applyViewStates(entries: ViewStateUpdate[]): void\n setTableState(tableId: number, state: string, props: Record<string, unknown>): void\n getViewState(id: number): ViewStateSnapshot | null\n}\n\nlet engine: Engine | null = null\nlet initError: unknown = null\ntry {\n engine = NitroModules.createHybridObject<TamaguiRegistry>('TamaguiRegistry') as Engine\n} catch (error) {\n initError = error\n}\n\nexport function isAvailable(): boolean {\n return engine !== null\n}\n\nfunction getEngine(): Engine {\n if (engine) return engine\n const detail = initError instanceof Error ? ` ${initError.message}` : ''\n throw new Error(\n `[@tamagui/native-registry] TamaguiRegistry failed to initialize; is react-native-nitro-modules installed and the app rebuilt?${detail}`\n )\n}\n\n/**\n * Extract the opaque ShadowNode JSI wrapper from a Fabric host component ref.\n * Same internals access as Unistyles; verified against RN 0.86.\n */\nfunction getShadowNode(ref: unknown): unknown | null {\n const handle = (ref as Record<string, unknown>)?.__internalInstanceHandle as\n | { stateNode?: { node?: unknown } }\n | undefined\n return handle?.stateNode?.node ?? null\n}\n\n/**\n * Nitro hybrid views parse props only from JSI values (their component\n * descriptor uses the JSI RawPropsParser), so the folly props this engine\n * commits, like React Native's own setNativeProps, abort in them. Every\n * Nitro view declares its `hybridRef` prop; those hosts stay unlinked and\n * re-theme through React renders.\n */\nfunction isNitroHybridView(ref: unknown): boolean {\n const config = (ref as { __viewConfig?: { validAttributes?: object } })?.__viewConfig\n return !!config?.validAttributes && 'hybridRef' in config.validAttributes\n}\n\n/**\n * Link a mounted view to the engine. Captures the ShadowNode once, returns\n * a handle keyed by the engine-issued id: unlink never re-derives anything\n * from the ref, so a torn-down ref cannot leave a stale entry behind.\n *\n * `table` is either the view's own slots or the id of a shared table filled\n * by setTableState; every view of one compiler mapping links the same table,\n * so linking sends no props at all. `commitNow` commits the view's active\n * state once, for a host whose render raced a scope change. Props arrive in\n * engine form, already through processStyleColors.\n */\nexport function link(\n ref: unknown,\n table: ViewSlots | number,\n scopeId: string = ROOT_SCOPE,\n commitNow = false\n): LinkHandle | null {\n if (isNitroHybridView(ref)) return null\n const node = getShadowNode(ref)\n if (!node) return null\n\n const e = getEngine()\n const id = e.link(node, table, scopeId, commitNow)\n let unlinked = false\n return {\n id,\n unlink: () => {\n if (unlinked) return\n unlinked = true\n e.unlink(id)\n },\n }\n}\n\n/**\n * Link many host views to shared tables in one native call. Entry i links\n * refs[i] to table tableIds[i] under scope scopes[scopeIndexes[i]]. Returns\n * the id of entry 0; ids are consecutive, and an entry whose host has no\n * shadow node consumes its id unlinked. The refs are React Native host\n * components (never Nitro views, see link).\n */\nexport function linkTables(\n refs: unknown[],\n tableIds: number[],\n scopeIndexes: number[],\n scopes: string[]\n): number {\n const nodes = new Array(refs.length)\n for (let i = 0; i < refs.length; i++) {\n nodes[i] = getShadowNode(refs[i])\n }\n return getEngine().linkTables(nodes, tableIds, scopeIndexes, scopes)\n}\n\n/** Unlink by an id from linkTables. Safe to call twice. */\nexport function unlink(id: number): void {\n getEngine().unlink(id)\n}\n\n/**\n * Batched per-view state selection: cold entries carry `props` (computed by\n * the caller, colors already processed via processStyleColors), warm entries\n * just name the state. One native commit for the whole batch.\n */\nexport function applyViewStates(entries: ViewStateUpdate[]): void {\n if (entries.length === 0) return\n getEngine().applyViewStates(entries)\n}\n\n/**\n * Fill one state of a shared table. Every view linked to the table reads it;\n * views already showing that state commit the new props. Props arrive in\n * engine form, already through processStyleColors.\n */\nexport function setTableState(\n tableId: number,\n state: string,\n props: Record<string, unknown>\n): void {\n getEngine().setTableState(tableId, state, props)\n}\n\n/**\n * Set the active state name (e.g. theme name) for a scope and commit the\n * update natively. The JS mirror updates first so any concurrent React\n * render paints the same styles the engine commits.\n */\nexport function setStateName(stateName: string, scopeId: string = ROOT_SCOPE): void {\n setMirroredStateName(scopeId, stateName)\n getEngine().setStateName(scopeId, stateName)\n}\n\nexport function removeScope(scopeId: string): void {\n removeMirroredScope(scopeId)\n getEngine().removeScope(scopeId)\n}\n\n/** Resolve the props a view should render right now, mirror-consistent. */\nexport function resolveSlots(\n slots: ViewSlots,\n scopeId: string = ROOT_SCOPE\n): Record<string, unknown> {\n const name = getMirroredStateName(scopeId)\n return {\n ...slots.base,\n ...(name ? slots.state?.[name] : undefined),\n }\n}\n\n/** Debug/test introspection of a linked view's engine tables. Not a hot path. */\nexport function getViewState(id: number): ViewStateSnapshot | null {\n if (!engine) return null\n return engine.getViewState(id)\n}\n\nexport function getStats(): RegistryStats {\n if (!engine) return { viewCount: 0, commitCount: 0, missCount: 0 }\n return {\n viewCount: engine.getViewCount(),\n commitCount: engine.getCommitCount(),\n missCount: engine.getMissCount(),\n }\n}\n"
9
+ "/**\n * Native implementation backed by the TamaguiRegistry Nitro HybridObject.\n * The C++ engine commits style updates directly to Fabric's ShadowTree via\n * UIManager::updateShadowTree (RN >= 0.81), with zero React re-renders.\n */\nimport { NitroModules } from 'react-native-nitro-modules'\nimport type { TamaguiRegistry } from './specs/TamaguiRegistry.nitro'\nimport type {\n LinkHandle,\n RegistryStats,\n Unlink,\n ViewSlots,\n ViewStateSnapshot,\n ViewStateUpdate,\n} from './types'\nimport {\n ROOT_SCOPE,\n getMirroredStateName,\n removeMirroredScope,\n setMirroredStateName,\n} from './mirror'\n\nexport type {\n LinkHandle,\n RegistryStats,\n Unlink,\n ViewSlots,\n ViewStateSnapshot,\n ViewStateUpdate,\n} from './types'\nexport { ROOT_SCOPE, getMirroredStateName } from './mirror'\nexport { processStyleColors } from './processStyleColors.native'\n\n/** Full engine surface: typed Nitro methods plus the raw-JSI methods. */\ninterface Engine extends TamaguiRegistry {\n link(\n shadowNode: unknown,\n table: ViewSlots | number,\n scopeId: string,\n commitNow: boolean\n ): number\n linkTables(\n shadowNodes: unknown[],\n tableIds: number[],\n scopeIndexes: number[],\n scopes: string[]\n ): void\n applyViewStates(entries: ViewStateUpdate[]): void\n setTableState(tableId: number, state: string, props: Record<string, unknown>): void\n getViewState(id: number): ViewStateSnapshot | null\n}\n\nlet engine: Engine | null = null\nlet initError: unknown = null\ntry {\n engine = NitroModules.createHybridObject<TamaguiRegistry>('TamaguiRegistry') as Engine\n} catch (error) {\n initError = error\n}\n\nexport function isAvailable(): boolean {\n return engine !== null\n}\n\nfunction getEngine(): Engine {\n if (engine) return engine\n const detail = initError instanceof Error ? ` ${initError.message}` : ''\n throw new Error(\n `[@tamagui/native-registry] TamaguiRegistry failed to initialize; is react-native-nitro-modules installed and the app rebuilt?${detail}`\n )\n}\n\n/**\n * Extract the opaque ShadowNode JSI wrapper from a Fabric host component ref.\n * Same internals access as Unistyles; verified against RN 0.86.\n */\nfunction getShadowNode(ref: unknown): unknown | null {\n const handle = (ref as Record<string, unknown>)?.__internalInstanceHandle as\n | { stateNode?: { node?: unknown } }\n | undefined\n return handle?.stateNode?.node ?? null\n}\n\n/**\n * Nitro hybrid views parse props only from JSI values (their component\n * descriptor uses the JSI RawPropsParser), so the folly props this engine\n * commits, like React Native's own setNativeProps, abort in them. Every\n * Nitro view declares its `hybridRef` prop; those hosts stay unlinked and\n * re-theme through React renders.\n */\nfunction isNitroHybridView(ref: unknown): boolean {\n const config = (ref as { __viewConfig?: { validAttributes?: object } })?.__viewConfig\n return !!config?.validAttributes && 'hybridRef' in config.validAttributes\n}\n\n/**\n * Link a mounted view to the engine. Captures the ShadowNode once, returns\n * a handle keyed by the engine-issued id: unlink never re-derives anything\n * from the ref, so a torn-down ref cannot leave a stale entry behind.\n *\n * `table` is either the view's own slots or the id of a shared table filled\n * by setTableState; every view of one compiler mapping links the same table,\n * so linking sends no props at all. `commitNow` commits the view's active\n * state once, for a host whose render raced a scope change. Props arrive in\n * engine form, already through processStyleColors.\n */\nexport function link(\n ref: unknown,\n table: ViewSlots | number,\n scopeId: string = ROOT_SCOPE,\n commitNow = false\n): LinkHandle | null {\n if (isNitroHybridView(ref)) return null\n const node = getShadowNode(ref)\n if (!node) return null\n\n const e = getEngine()\n const id = e.link(node, table, scopeId, commitNow)\n let unlinked = false\n return {\n id,\n unlink: () => {\n if (unlinked) return\n unlinked = true\n e.unlink(id)\n },\n }\n}\n\n/**\n * Link many host views to shared tables in one native call. Entry i links\n * refs[i] to table tableIds[i] under scope scopes[scopeIndexes[i]]. A host\n * already linked to a table moves to its new entry, and the engine drops\n * linked views that left the tree, so table links need no unlink. The refs\n * are React Native host components (never Nitro views, see link).\n */\nexport function linkTables(\n refs: unknown[],\n tableIds: number[],\n scopeIndexes: number[],\n scopes: string[]\n): void {\n const nodes = new Array(refs.length)\n for (let i = 0; i < refs.length; i++) {\n nodes[i] = getShadowNode(refs[i])\n }\n getEngine().linkTables(nodes, tableIds, scopeIndexes, scopes)\n}\n\n/** Unlink by an id from link. Safe to call twice. */\nexport function unlink(id: number): void {\n getEngine().unlink(id)\n}\n\n/**\n * Batched per-view state selection: cold entries carry `props` (computed by\n * the caller, colors already processed via processStyleColors), warm entries\n * just name the state. One native commit for the whole batch.\n */\nexport function applyViewStates(entries: ViewStateUpdate[]): void {\n if (entries.length === 0) return\n getEngine().applyViewStates(entries)\n}\n\n/**\n * Fill one state of a shared table. Every view linked to the table reads it;\n * views already showing that state commit the new props. Props arrive in\n * engine form, already through processStyleColors.\n */\nexport function setTableState(\n tableId: number,\n state: string,\n props: Record<string, unknown>\n): void {\n getEngine().setTableState(tableId, state, props)\n}\n\n/**\n * Set the active state name (e.g. theme name) for a scope and commit the\n * update natively. The JS mirror updates first so any concurrent React\n * render paints the same styles the engine commits.\n */\nexport function setStateName(stateName: string, scopeId: string = ROOT_SCOPE): void {\n setMirroredStateName(scopeId, stateName)\n getEngine().setStateName(scopeId, stateName)\n}\n\nexport function removeScope(scopeId: string): void {\n removeMirroredScope(scopeId)\n getEngine().removeScope(scopeId)\n}\n\n/** Resolve the props a view should render right now, mirror-consistent. */\nexport function resolveSlots(\n slots: ViewSlots,\n scopeId: string = ROOT_SCOPE\n): Record<string, unknown> {\n const name = getMirroredStateName(scopeId)\n return {\n ...slots.base,\n ...(name ? slots.state?.[name] : undefined),\n }\n}\n\n/** Debug/test introspection of a linked view's engine tables. Not a hot path. */\nexport function getViewState(id: number): ViewStateSnapshot | null {\n if (!engine) return null\n return engine.getViewState(id)\n}\n\nexport function getStats(): RegistryStats {\n if (!engine) return { viewCount: 0, commitCount: 0, missCount: 0 }\n return {\n viewCount: engine.getViewCount(),\n commitCount: engine.getCommitCount(),\n missCount: engine.getMissCount(),\n }\n}\n"
10
10
  ]
11
11
  }