@symbiote-native/engine 1.2.0 → 1.3.1
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/android/CMakeLists.txt +31 -1
- package/android/build.gradle +4 -1
- package/build/accessibility-info/index.android.js +21 -17
- package/build/accessibility-info/index.ios.js +2 -0
- package/build/accessibility-info/shared.d.ts +1 -1
- package/build/accessibility-props.d.ts +0 -11
- package/build/accessibility-props.js +30 -68
- package/build/alert/shared.d.ts +1 -1
- package/build/alert/shared.js +3 -7
- package/build/animated/graph.js +1 -1
- package/build/animated/leaf-lifecycle.js +2 -2
- package/build/app-state/index.d.ts +1 -1
- package/build/app-state/index.js +35 -27
- package/build/asset-source-resolver.d.ts +2 -0
- package/build/asset-source-resolver.js +13 -0
- package/build/back-handler/index.d.ts +7 -6
- package/build/back-handler/index.js +19 -16
- package/build/debug.js +8 -22
- package/build/dispatch.js +3 -9
- package/build/events/index.js +12 -3
- package/build/fabric-props.js +75 -180
- package/build/fabric.d.ts +2 -8
- package/build/fabric.js +27 -33
- package/build/host-access.d.ts +1 -128
- package/build/host-access.js +96 -205
- package/build/host-behavior.d.ts +1 -100
- package/build/host-behavior.js +125 -311
- package/build/image-loader.d.ts +4 -2
- package/build/image-loader.js +24 -48
- package/build/image-source-resolver.js +3 -7
- package/build/image-source-write.d.ts +1 -12
- package/build/image-source-write.js +28 -36
- package/build/imperative.d.ts +0 -28
- package/build/imperative.js +42 -92
- package/build/index.d.ts +3 -2
- package/build/index.js +30 -43
- package/build/invariant.d.ts +1 -0
- package/build/invariant.js +10 -0
- package/build/keyboard/index.js +11 -32
- package/build/linking/index.android.js +5 -3
- package/build/linking/shared.d.ts +1 -1
- package/build/linking/shared.js +16 -19
- package/build/mutation-buffer.d.ts +0 -177
- package/build/mutation-buffer.js +137 -308
- package/build/native-engine.d.ts +0 -102
- package/build/native-engine.js +38 -98
- package/build/native-events.d.ts +5 -0
- package/build/native-events.js +30 -18
- package/build/native-tree-host.d.ts +0 -21
- package/build/native-tree-host.js +14 -31
- package/build/node.d.ts +0 -212
- package/build/node.js +354 -774
- package/build/permissions-android/index.android.d.ts +59 -0
- package/build/permissions-android/index.android.js +47 -0
- package/build/permissions-android/index.d.ts +1 -115
- package/build/permissions-android/index.ios.d.ts +59 -0
- package/build/permissions-android/index.ios.js +31 -0
- package/build/permissions-android/index.js +3 -184
- package/build/permissions-android/shared.d.ts +63 -0
- package/build/permissions-android/shared.js +66 -0
- package/build/platform/index.android.js +3 -5
- package/build/platform/index.ios.js +3 -3
- package/build/platform/shared.d.ts +4 -0
- package/build/platform/shared.js +9 -0
- package/build/platform-color/index.android.d.ts +4 -0
- package/build/platform-color/index.android.js +7 -0
- package/build/platform-color/index.d.ts +2 -20
- package/build/platform-color/index.js +1 -45
- package/build/platform-color/shared.d.ts +21 -0
- package/build/platform-color/shared.js +41 -0
- package/build/post-commit.js +3 -8
- package/build/process-aspect-ratio.js +3 -7
- package/build/process-background-longhands.js +10 -19
- package/build/process-filter.js +11 -19
- package/build/process-font-variant.js +3 -7
- package/build/registry.d.ts +0 -33
- package/build/registry.js +22 -57
- package/build/report-error.js +4 -18
- package/build/settings/index.android.d.ts +6 -0
- package/build/settings/index.android.js +21 -0
- package/build/settings/index.d.ts +1 -8
- package/build/settings/index.ios.d.ts +8 -0
- package/build/settings/index.ios.js +122 -0
- package/build/settings/index.js +3 -122
- package/build/share/index.android.js +9 -32
- package/build/share/index.ios.js +14 -15
- package/build/share/shared.d.ts +4 -2
- package/build/share/shared.js +7 -10
- package/build/status-bar/index.android.js +1 -1
- package/build/status-bar/index.ios.js +4 -3
- package/build/structured-style.d.ts +0 -9
- package/build/structured-style.js +16 -31
- package/build/styles.js +3 -6
- package/build/surface.d.ts +0 -26
- package/build/surface.js +29 -76
- package/build/text-input-state.js +4 -8
- package/build/toast-android/index.android.d.ts +10 -0
- package/build/toast-android/index.android.js +108 -0
- package/build/toast-android/index.d.ts +1 -10
- package/build/toast-android/index.ios.d.ts +10 -0
- package/build/toast-android/index.ios.js +19 -0
- package/build/toast-android/index.js +3 -108
- package/build/touch-history.js +5 -11
- package/build/tree-host.d.ts +0 -270
- package/build/tree-host.js +63 -153
- package/build/view-config.js +17 -37
- package/cpp/SymbioteFabricProps.cpp +204 -120
- package/cpp/SymbioteFabricProps.h +5 -0
- package/cpp/SymbioteTree.cpp +20 -6
- package/package.json +2 -2
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// Settings module: reads/writes the app's persisted defaults (iOS NSUserDefaults
|
|
2
|
+
// via the native SettingsManager). A JS-side snapshot seeded from the native module
|
|
3
|
+
// constants answers `get`; `set` writes through to native and updates the snapshot;
|
|
4
|
+
// `watchKeys`/`clearWatch` are a pure-JS subscription registry that fires when a
|
|
5
|
+
// watched key's value changes. Native re-broadcasts external edits through the
|
|
6
|
+
// device event `settingsUpdated`, which feeds the same change->fire path. Mirrors
|
|
7
|
+
// RN's Libraries/Settings/Settings.ios.js, iOS surface only.
|
|
8
|
+
import { installDeviceEventHub, NativeEventEmitter, } from '../native-events.js';
|
|
9
|
+
import { getNativeModule } from '../native-modules/index.js';
|
|
10
|
+
import { dlog } from '../debug.js';
|
|
11
|
+
import { isRecord } from '../type-guards.js';
|
|
12
|
+
// The iOS native module name RN registers this under. NOTE: this is the name the
|
|
13
|
+
// iOS JS wrapper resolves via `TurboModuleRegistry.getEnforcing('SettingsManager')`.
|
|
14
|
+
// The spec filename is `INativeSettingsManager`. A module name is only provable on a
|
|
15
|
+
// real host (a headless fake answers to any name); this iOS name is device-verify-pending.
|
|
16
|
+
const SETTINGS_MODULE = 'SettingsManager';
|
|
17
|
+
// The device event native emits when the app's defaults change out from under JS
|
|
18
|
+
// (e.g. a Settings.bundle edit). Its payload is a record of changed key->value.
|
|
19
|
+
const SETTINGS_UPDATED_EVENT = 'settingsUpdated';
|
|
20
|
+
// watchIds are handed out as the registry index, so the first watcher is 0. A
|
|
21
|
+
// cleared slot keeps its index (the array never shrinks) so later ids stay stable.
|
|
22
|
+
const FIRST_WATCH_ID = 0;
|
|
23
|
+
// Lazily resolved so importing this module has no native side effect. `null` when
|
|
24
|
+
// the module isn't linked (headless): the snapshot then starts empty and `set`
|
|
25
|
+
// updates only JS state + fires watchers.
|
|
26
|
+
let settingsModule;
|
|
27
|
+
function getModule() {
|
|
28
|
+
if (settingsModule === undefined) {
|
|
29
|
+
settingsModule = getNativeModule(SETTINGS_MODULE);
|
|
30
|
+
dlog(`Settings: module ${settingsModule ? 'resolved' : 'NOT resolved (null)'}`);
|
|
31
|
+
}
|
|
32
|
+
return settingsModule;
|
|
33
|
+
}
|
|
34
|
+
// The JS-side mirror of native defaults: seeded once from the module constants,
|
|
35
|
+
// kept in sync by `set` and by the `settingsUpdated` device event.
|
|
36
|
+
let snapshot;
|
|
37
|
+
function getSnapshot() {
|
|
38
|
+
if (snapshot === undefined) {
|
|
39
|
+
const module = getModule();
|
|
40
|
+
const constants = module?.getConstants().settings;
|
|
41
|
+
snapshot = isRecord(constants) ? { ...constants } : {};
|
|
42
|
+
dlog(`Settings: snapshot seeded with ${Object.keys(snapshot).length} key(s)`);
|
|
43
|
+
}
|
|
44
|
+
return snapshot;
|
|
45
|
+
}
|
|
46
|
+
const subscriptions = [];
|
|
47
|
+
// Fire every watcher whose key set covers `key`. Called only for keys that changed.
|
|
48
|
+
function fireWatchers(key) {
|
|
49
|
+
for (const sub of subscriptions) {
|
|
50
|
+
if (sub.callback !== null && sub.keys.includes(key))
|
|
51
|
+
sub.callback();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Fold a batch of new values into the snapshot, firing watchers for each key whose
|
|
55
|
+
// value actually changed. Shared by `set` (JS-originated) and the device event
|
|
56
|
+
// (native-originated), matching RN's `_sendObservations`.
|
|
57
|
+
function applyChanges(values) {
|
|
58
|
+
const current = getSnapshot();
|
|
59
|
+
for (const key of Object.keys(values)) {
|
|
60
|
+
const next = values[key];
|
|
61
|
+
const didChange = current[key] !== next;
|
|
62
|
+
current[key] = next;
|
|
63
|
+
if (didChange)
|
|
64
|
+
fireWatchers(key);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
let emitter;
|
|
68
|
+
// Subscribe to native's `settingsUpdated` so external edits flow into the snapshot.
|
|
69
|
+
// WHY lazy + module-gated: importing this file must have no native side effect, and
|
|
70
|
+
// with no native module there is nothing native to observe, so a headless run that
|
|
71
|
+
// never installs the device hub doesn't crash. Idempotent.
|
|
72
|
+
function subscribeToNative() {
|
|
73
|
+
if (emitter !== undefined)
|
|
74
|
+
return;
|
|
75
|
+
const module = getModule();
|
|
76
|
+
if (module === null)
|
|
77
|
+
return;
|
|
78
|
+
installDeviceEventHub();
|
|
79
|
+
emitter = new NativeEventEmitter(module);
|
|
80
|
+
emitter.addListener(SETTINGS_UPDATED_EVENT, payload => {
|
|
81
|
+
if (!isRecord(payload))
|
|
82
|
+
return;
|
|
83
|
+
applyChanges(payload);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
class SettingsImpl {
|
|
87
|
+
// Read the current value for `key` from the JS snapshot. `undefined` if unset.
|
|
88
|
+
get(key) {
|
|
89
|
+
subscribeToNative();
|
|
90
|
+
return getSnapshot()[key];
|
|
91
|
+
}
|
|
92
|
+
// Persist `settings` to native, update the snapshot, and fire watchers for the
|
|
93
|
+
// keys that changed. Without a native module (headless) only JS state updates.
|
|
94
|
+
set(settings) {
|
|
95
|
+
subscribeToNative();
|
|
96
|
+
const module = getModule();
|
|
97
|
+
if (module === null) {
|
|
98
|
+
dlog('Settings.set -> no module (JS snapshot + watchers only)');
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
module.setValues(settings);
|
|
102
|
+
}
|
|
103
|
+
applyChanges(settings);
|
|
104
|
+
}
|
|
105
|
+
// Register a watcher for one or more keys. Returns a numeric watchId (the registry
|
|
106
|
+
// index) to pass to `clearWatch`.
|
|
107
|
+
watchKeys(keys, callback) {
|
|
108
|
+
subscribeToNative();
|
|
109
|
+
const watched = typeof keys === 'string' ? [keys] : keys;
|
|
110
|
+
const watchId = subscriptions.length + FIRST_WATCH_ID;
|
|
111
|
+
subscriptions.push({ keys: watched, callback });
|
|
112
|
+
return watchId;
|
|
113
|
+
}
|
|
114
|
+
// Disarm the watcher with the given id. Its slot is emptied (kept, not removed) so
|
|
115
|
+
// every other watchId stays valid.
|
|
116
|
+
clearWatch(watchId) {
|
|
117
|
+
if (watchId >= FIRST_WATCH_ID && watchId < subscriptions.length) {
|
|
118
|
+
subscriptions[watchId] = { keys: [], callback: null };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
export const Settings = new SettingsImpl();
|
package/build/settings/index.js
CHANGED
|
@@ -1,122 +1,3 @@
|
|
|
1
|
-
// Settings
|
|
2
|
-
//
|
|
3
|
-
|
|
4
|
-
// `watchKeys`/`clearWatch` are a pure-JS subscription registry that fires when a
|
|
5
|
-
// watched key's value changes. Native re-broadcasts external edits through the
|
|
6
|
-
// device event `settingsUpdated`, which feeds the same change->fire path. Mirrors
|
|
7
|
-
// RN's Libraries/Settings/Settings.ios.js, iOS surface only.
|
|
8
|
-
import { installDeviceEventHub, NativeEventEmitter, } from '../native-events.js';
|
|
9
|
-
import { getNativeModule } from '../native-modules/index.js';
|
|
10
|
-
import { dlog } from '../debug.js';
|
|
11
|
-
import { isRecord } from '../type-guards.js';
|
|
12
|
-
// The iOS native module name RN registers this under. NOTE: this is the name the
|
|
13
|
-
// iOS JS wrapper resolves via `TurboModuleRegistry.getEnforcing('SettingsManager')`.
|
|
14
|
-
// The spec filename is `INativeSettingsManager`. A module name is only provable on a
|
|
15
|
-
// real host (a headless fake answers to any name); this iOS name is device-verify-pending.
|
|
16
|
-
const SETTINGS_MODULE = 'SettingsManager';
|
|
17
|
-
// The device event native emits when the app's defaults change out from under JS
|
|
18
|
-
// (e.g. a Settings.bundle edit). Its payload is a record of changed key->value.
|
|
19
|
-
const SETTINGS_UPDATED_EVENT = 'settingsUpdated';
|
|
20
|
-
// watchIds are handed out as the registry index, so the first watcher is 0. A
|
|
21
|
-
// cleared slot keeps its index (the array never shrinks) so later ids stay stable.
|
|
22
|
-
const FIRST_WATCH_ID = 0;
|
|
23
|
-
// Lazily resolved so importing this module has no native side effect. `null` when
|
|
24
|
-
// the module isn't linked (headless): the snapshot then starts empty and `set`
|
|
25
|
-
// updates only JS state + fires watchers.
|
|
26
|
-
let settingsModule;
|
|
27
|
-
function getModule() {
|
|
28
|
-
if (settingsModule === undefined) {
|
|
29
|
-
settingsModule = getNativeModule(SETTINGS_MODULE);
|
|
30
|
-
dlog(`Settings: module ${settingsModule ? 'resolved' : 'NOT resolved (null)'}`);
|
|
31
|
-
}
|
|
32
|
-
return settingsModule;
|
|
33
|
-
}
|
|
34
|
-
// The JS-side mirror of native defaults: seeded once from the module constants,
|
|
35
|
-
// kept in sync by `set` and by the `settingsUpdated` device event.
|
|
36
|
-
let snapshot;
|
|
37
|
-
function getSnapshot() {
|
|
38
|
-
if (snapshot === undefined) {
|
|
39
|
-
const module = getModule();
|
|
40
|
-
const constants = module?.getConstants().settings;
|
|
41
|
-
snapshot = isRecord(constants) ? { ...constants } : {};
|
|
42
|
-
dlog(`Settings: snapshot seeded with ${Object.keys(snapshot).length} key(s)`);
|
|
43
|
-
}
|
|
44
|
-
return snapshot;
|
|
45
|
-
}
|
|
46
|
-
const subscriptions = [];
|
|
47
|
-
// Fire every watcher whose key set covers `key`. Called only for keys that changed.
|
|
48
|
-
function fireWatchers(key) {
|
|
49
|
-
for (const sub of subscriptions) {
|
|
50
|
-
if (sub.callback !== null && sub.keys.includes(key))
|
|
51
|
-
sub.callback();
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
// Fold a batch of new values into the snapshot, firing watchers for each key whose
|
|
55
|
-
// value actually changed. Shared by `set` (JS-originated) and the device event
|
|
56
|
-
// (native-originated), matching RN's `_sendObservations`.
|
|
57
|
-
function applyChanges(values) {
|
|
58
|
-
const current = getSnapshot();
|
|
59
|
-
for (const key of Object.keys(values)) {
|
|
60
|
-
const next = values[key];
|
|
61
|
-
const didChange = current[key] !== next;
|
|
62
|
-
current[key] = next;
|
|
63
|
-
if (didChange)
|
|
64
|
-
fireWatchers(key);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
let emitter;
|
|
68
|
-
// Subscribe to native's `settingsUpdated` so external edits flow into the snapshot.
|
|
69
|
-
// WHY lazy + module-gated: importing this file must have no native side effect, and
|
|
70
|
-
// with no native module there is nothing native to observe, so a headless run that
|
|
71
|
-
// never installs the device hub doesn't crash. Idempotent.
|
|
72
|
-
function subscribeToNative() {
|
|
73
|
-
if (emitter !== undefined)
|
|
74
|
-
return;
|
|
75
|
-
const module = getModule();
|
|
76
|
-
if (module === null)
|
|
77
|
-
return;
|
|
78
|
-
installDeviceEventHub();
|
|
79
|
-
emitter = new NativeEventEmitter(module);
|
|
80
|
-
emitter.addListener(SETTINGS_UPDATED_EVENT, payload => {
|
|
81
|
-
if (!isRecord(payload))
|
|
82
|
-
return;
|
|
83
|
-
applyChanges(payload);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
class SettingsImpl {
|
|
87
|
-
// Read the current value for `key` from the JS snapshot. `undefined` if unset.
|
|
88
|
-
get(key) {
|
|
89
|
-
subscribeToNative();
|
|
90
|
-
return getSnapshot()[key];
|
|
91
|
-
}
|
|
92
|
-
// Persist `settings` to native, update the snapshot, and fire watchers for the
|
|
93
|
-
// keys that changed. Without a native module (headless) only JS state updates.
|
|
94
|
-
set(settings) {
|
|
95
|
-
subscribeToNative();
|
|
96
|
-
const module = getModule();
|
|
97
|
-
if (module === null) {
|
|
98
|
-
dlog('Settings.set -> no module (JS snapshot + watchers only)');
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
module.setValues(settings);
|
|
102
|
-
}
|
|
103
|
-
applyChanges(settings);
|
|
104
|
-
}
|
|
105
|
-
// Register a watcher for one or more keys. Returns a numeric watchId (the registry
|
|
106
|
-
// index) to pass to `clearWatch`.
|
|
107
|
-
watchKeys(keys, callback) {
|
|
108
|
-
subscribeToNative();
|
|
109
|
-
const watched = typeof keys === 'string' ? [keys] : keys;
|
|
110
|
-
const watchId = subscriptions.length + FIRST_WATCH_ID;
|
|
111
|
-
subscriptions.push({ keys: watched, callback });
|
|
112
|
-
return watchId;
|
|
113
|
-
}
|
|
114
|
-
// Disarm the watcher with the given id. Its slot is emptied (kept, not removed) so
|
|
115
|
-
// every other watchId stays valid.
|
|
116
|
-
clearWatch(watchId) {
|
|
117
|
-
if (watchId >= FIRST_WATCH_ID && watchId < subscriptions.length) {
|
|
118
|
-
subscriptions[watchId] = { keys: [], callback: null };
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
export const Settings = new SettingsImpl();
|
|
1
|
+
// Settings: base / headless build. Metro picks index.ios.ts / index.android.ts on a device; off
|
|
2
|
+
// those, the iOS build (the SettingsManager-backed one) is the default.
|
|
3
|
+
export * from './index.ios.js';
|
|
@@ -9,47 +9,24 @@
|
|
|
9
9
|
// name, so it is only proven on a real Android host (a bridgeless resolution log there).
|
|
10
10
|
import { dlog } from '../debug.js';
|
|
11
11
|
import { getNativeModule } from '../native-modules/index.js';
|
|
12
|
-
import {
|
|
12
|
+
import { assertShareArgs, invariant, shareActions } from './shared.js';
|
|
13
13
|
const SHARE_MODULE = 'ShareModule';
|
|
14
|
-
// ShareModule.share resolves an untyped value at the native boundary; narrow it before
|
|
15
|
-
// reading `action` (no `as`).
|
|
16
|
-
function isShareResult(value) {
|
|
17
|
-
return (typeof value === 'object' &&
|
|
18
|
-
value !== null &&
|
|
19
|
-
'action' in value &&
|
|
20
|
-
typeof value.action === 'string');
|
|
21
|
-
}
|
|
22
14
|
export const Share = {
|
|
23
15
|
...shareActions,
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
// native result, or a missing module (explicit reject, never a hung Promise).
|
|
16
|
+
// Share.js's Android branch: every check is a synchronous invariant, and the native result
|
|
17
|
+
// passes through untouched under `activityType: null`.
|
|
27
18
|
share(content, options = {}) {
|
|
28
|
-
|
|
29
|
-
if (invalid !== null) {
|
|
30
|
-
dlog(`Share.share -> invalid content: ${invalid.message}`);
|
|
31
|
-
return Promise.reject(invalid);
|
|
32
|
-
}
|
|
19
|
+
assertShareArgs(content, options);
|
|
33
20
|
dlog('Share.share (android)');
|
|
34
21
|
const shareModule = getNativeModule(SHARE_MODULE);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return Promise.reject(new Error('Share: ShareModule native module unavailable'));
|
|
38
|
-
}
|
|
22
|
+
invariant(shareModule !== null, 'ShareModule should be registered on Android.');
|
|
23
|
+
invariant(content.title == null || typeof content.title === 'string', 'Invalid title: title should be a string.');
|
|
39
24
|
const newContent = {
|
|
40
25
|
title: content.title,
|
|
41
26
|
message: typeof content.message === 'string' ? content.message : undefined,
|
|
42
27
|
};
|
|
43
|
-
return shareModule
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
throw new Error('Share: ShareModule returned an unexpected result');
|
|
47
|
-
}
|
|
48
|
-
dlog(`Share.share -> android action=${result.action}`);
|
|
49
|
-
return {
|
|
50
|
-
action: result.action === DISMISSED_ACTION ? DISMISSED_ACTION : SHARED_ACTION,
|
|
51
|
-
activityType: null,
|
|
52
|
-
};
|
|
53
|
-
});
|
|
28
|
+
return shareModule
|
|
29
|
+
.share(newContent, options.dialogTitle)
|
|
30
|
+
.then(result => ({ activityType: null, ...result }));
|
|
54
31
|
},
|
|
55
32
|
};
|
package/build/share/index.ios.js
CHANGED
|
@@ -7,39 +7,38 @@
|
|
|
7
7
|
import { dlog } from '../debug.js';
|
|
8
8
|
import { getNativeModule } from '../native-modules/index.js';
|
|
9
9
|
import { ACTION_SHEET_MANAGER, } from '../action-sheet-ios/index.js';
|
|
10
|
-
import {
|
|
10
|
+
import { isProcessableColor, processColor } from '../platform-color';
|
|
11
|
+
import { assertShareArgs, invariant, shareActions, SHARED_ACTION, DISMISSED_ACTION, } from './shared.js';
|
|
11
12
|
export const Share = {
|
|
12
13
|
...shareActions,
|
|
13
14
|
// Open the iOS share sheet for `content`. Resolves with the user's action
|
|
14
15
|
// (sharedAction / dismissedAction); rejects on invalid content, a native failure,
|
|
15
16
|
// or a missing module (explicit reject rather than a Promise that never settles).
|
|
16
17
|
share(content, options = {}) {
|
|
17
|
-
|
|
18
|
-
if (invalid !== null) {
|
|
19
|
-
dlog(`Share.share -> invalid content: ${invalid.message}`);
|
|
20
|
-
return Promise.reject(invalid);
|
|
21
|
-
}
|
|
18
|
+
assertShareArgs(content, options);
|
|
22
19
|
dlog('Share.share (ios)');
|
|
23
|
-
|
|
24
|
-
if (manager === null) {
|
|
25
|
-
dlog(`Share: "${ACTION_SHEET_MANAGER}" unresolved`);
|
|
26
|
-
return Promise.reject(new Error('Share: ActionSheetManager native module unavailable'));
|
|
27
|
-
}
|
|
20
|
+
// Share.js's iOS branch: both invariants run INSIDE the executor, so they reject.
|
|
28
21
|
return new Promise((resolve, reject) => {
|
|
22
|
+
const tintColor = isProcessableColor(options.tintColor)
|
|
23
|
+
? processColor(options.tintColor)
|
|
24
|
+
: undefined;
|
|
25
|
+
invariant(tintColor == null || typeof tintColor === 'number', 'Unexpected color given for options.tintColor');
|
|
26
|
+
const manager = getNativeModule(ACTION_SHEET_MANAGER);
|
|
27
|
+
invariant(manager !== null, 'NativeActionSheetManager is not registered on iOS, but it should be.');
|
|
29
28
|
manager.showShareActionSheetWithOptions({
|
|
30
29
|
message: typeof content.message === 'string' ? content.message : undefined,
|
|
31
30
|
url: typeof content.url === 'string' ? content.url : undefined,
|
|
32
31
|
subject: options.subject,
|
|
33
|
-
tintColor:
|
|
34
|
-
anchor: options.anchor,
|
|
32
|
+
tintColor: typeof tintColor === 'number' ? tintColor : undefined,
|
|
33
|
+
anchor: typeof options.anchor === 'number' ? options.anchor : undefined,
|
|
35
34
|
excludedActivityTypes: options.excludedActivityTypes,
|
|
36
35
|
}, error => {
|
|
37
36
|
dlog('Share.share -> failure');
|
|
38
|
-
reject(
|
|
37
|
+
reject(error);
|
|
39
38
|
}, (completed, activityType) => {
|
|
40
39
|
dlog(`Share.share -> success completed=${completed}`);
|
|
41
40
|
resolve(completed
|
|
42
|
-
? { action: SHARED_ACTION, activityType
|
|
41
|
+
? { action: SHARED_ACTION, activityType }
|
|
43
42
|
: { action: DISMISSED_ACTION, activityType: null });
|
|
44
43
|
});
|
|
45
44
|
});
|
package/build/share/shared.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { invariant } from '../invariant';
|
|
2
|
+
export { invariant };
|
|
1
3
|
export type IShareContent = {
|
|
2
4
|
title?: string;
|
|
3
5
|
url: string;
|
|
@@ -17,7 +19,7 @@ export interface IShareOptions {
|
|
|
17
19
|
export declare const SHARED_ACTION = "sharedAction";
|
|
18
20
|
export declare const DISMISSED_ACTION = "dismissedAction";
|
|
19
21
|
export interface IShareAction {
|
|
20
|
-
action:
|
|
22
|
+
action: string;
|
|
21
23
|
activityType?: string | null;
|
|
22
24
|
}
|
|
23
25
|
export interface IShareStatic {
|
|
@@ -29,4 +31,4 @@ export declare const shareActions: {
|
|
|
29
31
|
sharedAction: typeof SHARED_ACTION;
|
|
30
32
|
dismissedAction: typeof DISMISSED_ACTION;
|
|
31
33
|
};
|
|
32
|
-
export declare function
|
|
34
|
+
export declare function assertShareArgs(content: IShareContent, options: IShareOptions): void;
|
package/build/share/shared.js
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
// Metro selects the platform file on a real host (share.android.ts > share.ts); the base
|
|
8
8
|
// share.ts re-exports the iOS build for web/headless. There is no runtime `Platform.OS`
|
|
9
9
|
// read: the filename is the selector.
|
|
10
|
+
import { invariant } from '../invariant.js';
|
|
11
|
+
export { invariant };
|
|
10
12
|
// RN's Share action constants (RN Share.js ~173/179). These back the documented
|
|
11
13
|
// `result.action === Share.dismissedAction` pattern. True statically-known literals,
|
|
12
14
|
// so CONSTANT_CASE; the public fields (Share.sharedAction / Share.dismissedAction) are
|
|
@@ -19,14 +21,9 @@ export const shareActions = {
|
|
|
19
21
|
sharedAction: SHARED_ACTION,
|
|
20
22
|
dismissedAction: DISMISSED_ACTION,
|
|
21
23
|
};
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
if (typeof content.url !== 'string' && typeof content.message !== 'string') {
|
|
29
|
-
return new Error('At least one of URL or message is required');
|
|
30
|
-
}
|
|
31
|
-
return null;
|
|
24
|
+
// Share.js's three shared invariants, checked before any promise exists on both platforms.
|
|
25
|
+
export function assertShareArgs(content, options) {
|
|
26
|
+
invariant(typeof content === 'object' && content !== null, 'Content to share must be a valid object');
|
|
27
|
+
invariant(typeof content.url === 'string' || typeof content.message === 'string', 'At least one of URL or message is required');
|
|
28
|
+
invariant(typeof options === 'object' && options !== null, 'Options must be a valid object');
|
|
32
29
|
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// on device: show/hide + light/dark text survive the relayout without blanking.
|
|
12
12
|
import { getNativeModule } from '../native-modules/index.js';
|
|
13
13
|
import { dlog } from '../debug.js';
|
|
14
|
-
import { processColor } from '../platform-color
|
|
14
|
+
import { processColor } from '../platform-color';
|
|
15
15
|
import { STATUS_BAR_MANAGER, } from './shared.js';
|
|
16
16
|
// processColor returns `unknown` (its result is platform-dependent); narrow to the
|
|
17
17
|
// number Fabric/native expects, like RN's invariant before setColor. A non-number
|
|
@@ -17,9 +17,10 @@ import { STATUS_BAR_MANAGER, STATIC_HIDE_TRANSITION, hideTransition, } from './s
|
|
|
17
17
|
// __turboModuleProxy is installed. Non-enforcing: a declarative StatusBar must NOT crash the
|
|
18
18
|
// whole render if the module can't resolve.
|
|
19
19
|
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
20
|
+
// TODO(rn-parity): each StatusBar applies its props directly. RN keeps a stack instead:
|
|
21
|
+
// `_propsStack` over `_defaultProps`, unmount restores the previous entry, one batched native
|
|
22
|
+
// update, public push/pop/replaceStackEntry, `showHideTransition`, and static setters that warn
|
|
23
|
+
// on the wrong platform. Port it for both platforms and all 5 adapters.
|
|
23
24
|
export function applyStatusBarProps(props) {
|
|
24
25
|
const { barStyle, hidden, animated = false, networkActivityIndicatorVisible, } = props;
|
|
25
26
|
const manager = getNativeModule(STATUS_BAR_MANAGER);
|
|
@@ -1,10 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A style value with its structured keys resolved — the same value by identity when there was
|
|
3
|
-
* nothing to resolve, which is nearly always.
|
|
4
|
-
*
|
|
5
|
-
* Accepts what a style slot can hold: one object, or a (nested) array of them. An array is not
|
|
6
|
-
* memoized — `pushClassStyle` mints a fresh one on every publish, so a cache keyed on it could
|
|
7
|
-
* never hit; its ENTRIES carry the memo instead, and the original array comes back untouched when
|
|
8
|
-
* none of them moved.
|
|
9
|
-
*/
|
|
10
1
|
export declare function resolveStructuredStyle(style: unknown): unknown;
|
|
@@ -1,22 +1,12 @@
|
|
|
1
1
|
// The ten style keys RN parses in JS before native, and the one place they are resolved.
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// read.
|
|
11
|
-
//
|
|
12
|
-
// This is the same move `configPayloadFold` makes for a third-party view's own processors, one
|
|
13
|
-
// layer down: anything the C++ half cannot do has to happen before the C++ half sees the value.
|
|
14
|
-
//
|
|
15
|
-
// IDENTITY IS PART OF THE CONTRACT. A style object that needs nothing comes back BY IDENTITY, and
|
|
16
|
-
// so does an array whose every entry did. The host's `OP_SET_PROP` skips a same-identity write, and
|
|
17
|
-
// `pushClassStyle` compares what it is about to publish against what it published last — hand
|
|
18
|
-
// either of them a fresh object per write and an unchanged style becomes a write and a dirty node
|
|
19
|
-
// on every render.
|
|
2
|
+
// They run at write time, not payload-build time: SymbioteFabricProps.cpp doesn't carry these
|
|
3
|
+
// processors, so resolving only in fabric-props.ts leaves the device its raw CSS string, silently
|
|
4
|
+
// dropped (C++ parses a style string only under enableNativeCSSParsing, default false).
|
|
5
|
+
// Same move `configPayloadFold` makes for a third-party view's own processors: anything the C++
|
|
6
|
+
// half can't do has to happen before the C++ half sees the value.
|
|
7
|
+
// Identity is part of the contract: an object/array needing no resolution comes back by identity,
|
|
8
|
+
// since OP_SET_PROP skips a same-identity write and pushClassStyle diffs by reference — a fresh
|
|
9
|
+
// object per call would turn an unchanged style into a write and a dirty node every render.
|
|
20
10
|
import { processAspectRatio } from './process-aspect-ratio.js';
|
|
21
11
|
import { processBackgroundImage } from './process-background-image/index.js';
|
|
22
12
|
import { processBackgroundPosition, processBackgroundRepeat, processBackgroundSize, } from './process-background-longhands.js';
|
|
@@ -80,10 +70,9 @@ function asFontVariantInput(value) {
|
|
|
80
70
|
return value.filter(isString);
|
|
81
71
|
return '';
|
|
82
72
|
}
|
|
83
|
-
// transform accepts a CSS string
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
// [] (which would erase a valid transform).
|
|
73
|
+
// transform accepts a CSS string or an array of single-key records (the hot animated /
|
|
74
|
+
// sticky-header path). A non-string non-array value passes through verbatim — it may already be
|
|
75
|
+
// processed, so coercing it to [] would erase a valid transform.
|
|
87
76
|
function processTransformValue(value) {
|
|
88
77
|
if (typeof value === 'string')
|
|
89
78
|
return processTransform(value);
|
|
@@ -154,15 +143,11 @@ function resolveRecord(style) {
|
|
|
154
143
|
resolvedStyles.set(style, answer);
|
|
155
144
|
return answer;
|
|
156
145
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
* memoized — `pushClassStyle` mints a fresh one on every publish, so a cache keyed on it could
|
|
163
|
-
* never hit; its ENTRIES carry the memo instead, and the original array comes back untouched when
|
|
164
|
-
* none of them moved.
|
|
165
|
-
*/
|
|
146
|
+
// A style value with its structured keys resolved — same value by identity when nothing needed
|
|
147
|
+
// resolving, which is nearly always.
|
|
148
|
+
// Accepts one object or a (nested) array of them. An array itself isn't memoized (pushClassStyle
|
|
149
|
+
// mints a fresh one per publish, so a cache keyed on it would never hit); its entries carry the
|
|
150
|
+
// memo instead.
|
|
166
151
|
export function resolveStructuredStyle(style) {
|
|
167
152
|
if (Array.isArray(style)) {
|
|
168
153
|
let out;
|
package/build/styles.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
// The typed style surface (ViewStyle
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// react-native/Libraries/StyleSheet/StyleSheetTypes): the load-bearing layout / box /
|
|
5
|
-
// shadow / transform / text props, not the full surface. Agnostic types, so they
|
|
6
|
-
// live in the engine next to the style processors; every adapter re-exports them.
|
|
1
|
+
// The typed style surface (ViewStyle/TextStyle and friends). Maps onto Yoga layout props and RN's
|
|
2
|
+
// view/text props, which Fabric's C++ reads off the props payload. A correctly-typed subset of
|
|
3
|
+
// RN's StyleSheet surface — agnostic types, so every adapter re-exports them from the engine.
|
|
7
4
|
export {};
|
package/build/surface.d.ts
CHANGED
|
@@ -6,38 +6,12 @@ export declare class SymbioteSurface {
|
|
|
6
6
|
private readonly node;
|
|
7
7
|
private commitScheduled;
|
|
8
8
|
constructor(rootTag: IRootTag);
|
|
9
|
-
/**
|
|
10
|
-
* Every OTHER live surface, so one commit names every root — see `commitSurfaceOps`.
|
|
11
|
-
*
|
|
12
|
-
* Static because it reads a sibling instance's private handle, which only a member of this class
|
|
13
|
-
* may do. One surface — the universal case — allocates nothing.
|
|
14
|
-
*
|
|
15
|
-
* `self` may already be OUT of the registry: a teardown unregisters and then commits, and that
|
|
16
|
-
* commit is the one carrying the removals. So the fast path cannot be a size check — with one
|
|
17
|
-
* live surface left, `size === 1` means either "only me" or "only the other one", and taking the
|
|
18
|
-
* shortcut on the second reading is how a surface loses the very batch that empties it.
|
|
19
|
-
*/
|
|
20
9
|
private static others;
|
|
21
|
-
/**
|
|
22
|
-
* The top-level nodes, asked of the host.
|
|
23
|
-
*
|
|
24
|
-
* A getter rather than an array this class maintains: a second copy of a child list is the thing
|
|
25
|
-
* this design removes, and `nextSiblingOf` (host-access.ts) needs the same answer the host gives
|
|
26
|
-
* for a parented node.
|
|
27
|
-
*/
|
|
28
10
|
get children(): readonly ISymbioteNode[];
|
|
29
11
|
appendChild(child: ISymbioteNode): void;
|
|
30
12
|
insertBefore(child: ISymbioteNode, beforeChild: ISymbioteNode): void;
|
|
31
13
|
removeChild(child: ISymbioteNode): void;
|
|
32
14
|
clear(): void;
|
|
33
|
-
/**
|
|
34
|
-
* Release every host behavior still standing under this surface, at unmount.
|
|
35
|
-
*
|
|
36
|
-
* The sweep above cannot answer this: it only sees nodes a `removeChild` NOMINATED, and an
|
|
37
|
-
* unmount removes nothing — the adapter drops the whole surface. Without it every node keeps its
|
|
38
|
-
* `afterCommit` registration and its timers, and a restarted surface's commits drain the dead
|
|
39
|
-
* one's hooks forever.
|
|
40
|
-
*/
|
|
41
15
|
teardown(): void;
|
|
42
16
|
commit(): void;
|
|
43
17
|
requestCommit(): void;
|