@tamagui/native-registry 3.0.5 → 3.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cpp/HybridTamaguiRegistry.cpp +196 -65
- package/cpp/HybridTamaguiRegistry.hpp +29 -14
- package/dist/cjs/index.cjs +1 -3
- package/dist/cjs/index.native.cjs +1 -1
- package/dist/cjs/index.native.js +1 -1
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/esm/index.js +1 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.mjs +1 -3
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +1 -1
- package/dist/esm/index.native.js.map +1 -1
- package/package.json +3 -3
- package/src/index.native.ts +8 -8
- package/src/index.ts +1 -3
- package/types/index.d.ts +1 -1
- package/types/index.d.ts.map +2 -2
- package/types/index.native.d.ts +6 -6
- package/types/index.native.d.ts.map +1 -1
|
@@ -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
|
-
|
|
55
|
-
|
|
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
|
-
|
|
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
|
-
|
|
65
|
-
|
|
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]].
|
|
80
|
-
//
|
|
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
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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
|
-
|
|
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_.
|
|
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
|
-
//
|
|
205
|
-
//
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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
|
|
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
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
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
|
-
|
|
310
|
-
|
|
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()
|
|
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.
|
|
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
|
-
[
|
|
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
|
-
|
|
436
|
-
|
|
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
|
-
|
|
532
|
-
table->
|
|
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.
|
|
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
|
|
48
|
-
// the
|
|
49
|
-
//
|
|
50
|
-
//
|
|
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
|
-
|
|
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;
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -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
|
-
|
|
92
|
+
getEngine().linkTables(nodes, tableIds, scopeIndexes, scopes);
|
|
93
93
|
}
|
|
94
94
|
function unlink(id) {
|
|
95
95
|
getEngine().unlink(id);
|
package/dist/cjs/index.native.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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":"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"}
|
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) {}
|
package/dist/esm/index.js.map
CHANGED
|
@@ -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
|
|
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"}
|
package/dist/esm/index.mjs
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) {}
|
package/dist/esm/index.mjs.map
CHANGED
|
@@ -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
|
|
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"}
|
package/dist/esm/index.native.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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.
|
|
3
|
+
"version": "3.0.7",
|
|
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.
|
|
49
|
+
"@tamagui/build": "3.0.7",
|
|
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": "
|
|
80
|
+
"releaseSourceCommit": "96f8bc1f222af0381729a2e2202370aa4a9808ef"
|
|
81
81
|
}
|
package/src/index.native.ts
CHANGED
|
@@ -44,7 +44,7 @@ interface Engine extends TamaguiRegistry {
|
|
|
44
44
|
tableIds: number[],
|
|
45
45
|
scopeIndexes: number[],
|
|
46
46
|
scopes: string[]
|
|
47
|
-
):
|
|
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]].
|
|
133
|
-
*
|
|
134
|
-
*
|
|
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
|
-
):
|
|
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
|
-
|
|
147
|
+
getEngine().linkTables(nodes, tableIds, scopeIndexes, scopes)
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
/** Unlink by an id from
|
|
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
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[]):
|
|
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;
|
package/types/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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):
|
|
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
|
}
|
package/types/index.native.d.ts
CHANGED
|
@@ -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]].
|
|
21
|
-
*
|
|
22
|
-
*
|
|
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[]):
|
|
26
|
-
/** Unlink by an id from
|
|
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 ):
|
|
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
|
}
|