peachsim 0.1.2208 → 0.1.2209
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/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract-input.cjs +1 -1
- package/dist-lib/bridge-contract-input.mjs +1 -1
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/bundle-channel.cjs +448 -22
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +1 -1
- package/dist-lib/cloud.mjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/config.mjs +1 -1
- package/dist-lib/detox/index.cjs +2 -2
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/expo-swift-bundle.cjs +436 -16
- package/dist-lib/expo-swift-metadata.cjs +1 -1
- package/dist-lib/expo-swift-metadata.mjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +448 -22
- package/dist-lib/host/fetch-proxy-handler.cjs +4 -4
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +4 -4
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/kotlin-host.cjs +7 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +4 -4
- package/dist-lib/native-app-identity-project.cjs +2 -2
- package/dist-lib/native-app-identity-project.mjs +2 -2
- package/dist-lib/native-app-identity.cjs +1 -1
- package/dist-lib/native-app-identity.mjs +1 -1
- package/dist-lib/native-firebase-metadata.cjs +1 -1
- package/dist-lib/native-firebase-metadata.mjs +1 -1
- package/dist-lib/pdfium-raster.cjs +1 -1
- package/dist-lib/pdfium-raster.mjs +1 -1
- package/dist-lib/plist.cjs +1 -1
- package/dist-lib/plist.mjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/public-origins-lib-esm.json +24 -24
- package/dist-lib/public-origins-lib.json +59 -53
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/reap-browser.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +5482 -381
- package/dist-lib/swift-compile.cjs +98 -6
- package/dist-lib/swift-compile.mjs +98 -6
- package/dist-lib/swift-package.cjs +1 -1
- package/dist-lib/swift-package.mjs +1 -1
- package/dist-lib/swift-submit.cjs +1 -1
- package/dist-lib/swift-submit.mjs +1 -1
- package/dist-lib/swift-toolchain.cjs +1 -1
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite-swift.cjs +351 -13
- package/dist-lib/vite.cjs +4 -4
- package/dist-lib/worklet-executable.cjs +1 -1
- package/dist-lib/worklet-executable.mjs +1 -1
- package/dist-types/packages/peach-engine/src/engine/animated.d.ts +2 -1
- package/dist-types/packages/peach-engine/src/engine/animation-graph.d.ts +1 -0
- package/dist-types/packages/peach-engine/src/engine/liquid-glass.d.ts +6 -0
- package/dist-types/packages/peach-engine/src/engine/node.d.ts +1 -0
- package/dist-types/packages/peach-engine/src/engine/types.d.ts +1 -0
- package/dist-types/packages/peach-engine/src/render-worker/canvaskit-webgpu.d.ts +8 -0
- package/dist-types/packages/peach-engine/src/render-worker/compositor-gpu.d.ts +3 -0
- package/dist-types/packages/peach-engine/src/render-worker/compositor-protocol.d.ts +14 -0
- package/dist-types/packages/peach-engine/src/render-worker/compositor-runtime/render-tree.d.ts +18 -0
- package/kotlin/sdk.tar.gz +0 -0
- package/package.json +1 -1
- package/runtime-companion.json +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSCompoundPredicate.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSExpression.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSISO8601DateFormatter.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSMeasurementFormatter.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Intents.framework/Headers/INObjectCollection.h +27 -0
- package/sdk/ios/System/Library/Frameworks/Intents.framework/Headers/INObjectSection.h +24 -0
- package/sdk/ios/System/Library/Frameworks/Intents.framework/Headers/Intents.h +9 -0
- package/sdk/ios/System/Library/Frameworks/Intents.framework/Modules/module.modulemap +5 -0
- package/sdk/ios/System/Library/Frameworks/UIKit.framework/Headers/UIFeedbackGenerator.h +1 -1
- package/sdk/ios/System/Library/Frameworks/UIKit.framework/Headers/UIImpactFeedbackGenerator.h +1 -1
- package/sdk/ios/System/Library/Frameworks/UIKit.framework/Headers/UINibLoading.h +1 -1
- package/sdk/ios/System/Library/Frameworks/UIKit.framework/Headers/UINotificationFeedbackGenerator.h +1 -1
- package/sdk/ios/System/Library/Frameworks/UIKit.framework/Headers/UISelectionFeedbackGenerator.h +1 -1
- package/sdk/ios/usr/include/ObjectiveC.apinotes +7 -0
- package/src/android-theme.ts +136 -2
- package/src/expo-swift-host.ts +90 -1
- package/src/generated/android-framework-text.json +4566 -0
- package/src/generated/android-framework-themes.json +11 -0
- package/src/kotlin-app.ts +24 -4
- package/src/kotlin-host.ts +9 -0
- package/src/nitro-adapter.lock.json +246 -246
- package/src/nitro-superset.lock.json +4 -4
- package/src/swift-compile.ts +120 -2
- package/src/swift-distribution.lock.json +8 -8
- package/src/swift-objc-standin.ts +9 -2
- package/src/swift-shared-sdk.ts +2 -1
- package/src/swift-standin-builtin-behavior.ts +248 -0
- package/src/swift-standin-emit.ts +2 -0
- package/src/swift-standins.ts +17 -5
- package/src/turbo-runtime.lock.json +17 -17
package/dist-types/packages/peach-engine/src/render-worker/compositor-runtime/render-tree.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface RenderTree {
|
|
2
|
+
layerTexture(width: number, height: number): [number, GPUTexture];
|
|
3
|
+
released(): Uint32Array;
|
|
4
|
+
acquire(id: number): void;
|
|
5
|
+
release(id: number): void;
|
|
6
|
+
transaction(ops: Float64Array, published: Uint32Array): void;
|
|
7
|
+
commit(ops: Float64Array, published: Uint32Array): void;
|
|
8
|
+
composite(): Promise<{
|
|
9
|
+
texture: GPUTexture | null;
|
|
10
|
+
done: () => void;
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
13
|
+
export declare function renderTreeOf(context: object): RenderTree | null;
|
|
14
|
+
export declare class RenderThreadClock {
|
|
15
|
+
#private;
|
|
16
|
+
offsetMs(): number | null;
|
|
17
|
+
sample(): void;
|
|
18
|
+
}
|
package/kotlin/sdk.tar.gz
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/runtime-companion.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"abi":1,"sha256":"
|
|
1
|
+
{"abi":1,"sha256":"8d817e4a68a084ba50456a80439f20c8aa11c055d42c9cf1c7de017062bfd4a2","file":"node/cli-8d817e4a68a084ba50456a80439f20c8aa11c055d42c9cf1c7de017062bfd4a2.cjs"}
|
package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSCompoundPredicate.h
CHANGED
|
@@ -28,7 +28,7 @@ typedef NS_ENUM(NSUInteger, NSCompoundPredicateType) {
|
|
|
28
28
|
/// - An `OR` predicate with no subpredicates evaluates to <doc://com.apple.documentation/documentation/swift/false>.
|
|
29
29
|
/// - A compound predicate with one or more subpredicates evaluates to the truth of its subpredicates.
|
|
30
30
|
API_AVAILABLE(macos(10.4), ios(3.0), watchos(2.0), tvos(9.0))
|
|
31
|
-
|
|
31
|
+
@interface NSCompoundPredicate : NSPredicate
|
|
32
32
|
|
|
33
33
|
/// Returns the receiver that a specified type initializes using predicates from a specified array.
|
|
34
34
|
///
|
|
@@ -90,7 +90,7 @@ typedef NS_ENUM(NSUInteger, NSExpressionType) {
|
|
|
90
90
|
///
|
|
91
91
|
/// Although Core Data supports evaluation of the predefined functions, it doesn't support the evaluation of custom predicate functions in the persistent stores (during a fetch).
|
|
92
92
|
API_AVAILABLE(macos(10.4), ios(3.0), watchos(2.0), tvos(9.0))
|
|
93
|
-
|
|
93
|
+
@interface NSExpression : NSObject <NSSecureCoding, NSCopying> {
|
|
94
94
|
@package
|
|
95
95
|
struct _expressionFlags {
|
|
96
96
|
unsigned int _evaluationBlocked:1;
|
package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSISO8601DateFormatter.h
CHANGED
|
@@ -77,7 +77,7 @@ typedef NS_OPTIONS(NSUInteger, NSISO8601DateFormatOptions) {
|
|
|
77
77
|
/// > Tip:
|
|
78
78
|
/// > In Swift, you can use ``Date/ISO8601FormatStyle`` rather than ``ISO8601DateFormatter``. The ``FormatStyle`` API offers a declarative idiom for customizing the formatting of various types. Also, Foundation caches identical ``FormatStyle`` instances, so you don't need to pass them around your app, or risk wasting memory with duplicate formatters.
|
|
79
79
|
API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
|
|
80
|
-
|
|
80
|
+
@interface NSISO8601DateFormatter : NSFormatter <NSSecureCoding> {
|
|
81
81
|
@private
|
|
82
82
|
CFDateFormatterRef _formatter;
|
|
83
83
|
NSTimeZone *_timeZone;
|
package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSMeasurementFormatter.h
CHANGED
|
@@ -29,7 +29,7 @@ typedef NS_OPTIONS(NSUInteger, NSMeasurementFormatterUnitOptions) {
|
|
|
29
29
|
/// > Tip:
|
|
30
30
|
/// > In Swift, you can use ``Measurement/FormatStyle`` rather than ``MeasurementFormatter``. The ``FormatStyle`` API offers a declarative idiom for customizing the formatting of various types. Also, Foundation caches identical ``FormatStyle`` instances, so you don't need to pass them around your app, or risk wasting memory with duplicate formatters.
|
|
31
31
|
API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
|
|
32
|
-
|
|
32
|
+
@interface NSMeasurementFormatter : NSFormatter <NSSecureCoding> {
|
|
33
33
|
@private
|
|
34
34
|
void *_formatter;
|
|
35
35
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//
|
|
2
|
+
// INObjectCollection.h
|
|
3
|
+
// Intents
|
|
4
|
+
//
|
|
5
|
+
// Copyright © 2018-2024 Apple Inc. All rights reserved.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#import <Foundation/Foundation.h>
|
|
9
|
+
#import <Intents/INObjectSection.h>
|
|
10
|
+
|
|
11
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
12
|
+
|
|
13
|
+
API_AVAILABLE(ios(11.0), watchos(4.0), macos(10.12))
|
|
14
|
+
@interface INObjectCollection<ObjectType> : NSObject <NSCopying, NSSecureCoding>
|
|
15
|
+
|
|
16
|
+
@property (readonly, copy, nonatomic) NSArray<INObjectSection<ObjectType> *> *sections;
|
|
17
|
+
@property (readonly, copy, nonatomic) NSArray<ObjectType> *allItems;
|
|
18
|
+
@property (assign, nonatomic) BOOL usesIndexedCollation;
|
|
19
|
+
|
|
20
|
+
- (instancetype)initWithSections:(NSArray<INObjectSection<ObjectType> *> *)sections NS_DESIGNATED_INITIALIZER;
|
|
21
|
+
- (instancetype)initWithItems:(NSArray<ObjectType> *)items;
|
|
22
|
+
|
|
23
|
+
- (instancetype)init NS_UNAVAILABLE;
|
|
24
|
+
|
|
25
|
+
@end
|
|
26
|
+
|
|
27
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//
|
|
2
|
+
// INObjectSection.h
|
|
3
|
+
// Intents
|
|
4
|
+
//
|
|
5
|
+
// Copyright © 2018-2024 Apple Inc. All rights reserved.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#import <Foundation/Foundation.h>
|
|
9
|
+
|
|
10
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
11
|
+
|
|
12
|
+
API_AVAILABLE(ios(11.0), watchos(4.0), macos(10.12))
|
|
13
|
+
@interface INObjectSection<ObjectType> : NSObject <NSCopying, NSSecureCoding>
|
|
14
|
+
|
|
15
|
+
@property (readonly, nullable, copy, nonatomic) NSString *title;
|
|
16
|
+
@property (readonly, copy, nonatomic) NSArray<ObjectType> *items;
|
|
17
|
+
|
|
18
|
+
- (instancetype)initWithTitle:(nullable NSString *)title items:(NSArray<ObjectType> *)items NS_DESIGNATED_INITIALIZER;
|
|
19
|
+
|
|
20
|
+
- (instancetype)init NS_UNAVAILABLE;
|
|
21
|
+
|
|
22
|
+
@end
|
|
23
|
+
|
|
24
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -13,7 +13,7 @@ NS_HEADER_AUDIT_BEGIN(nullability, sendability)
|
|
|
13
13
|
|
|
14
14
|
// UIFeedbackGenerator is an abstract class that should not be used directly
|
|
15
15
|
UIKIT_EXTERN API_AVAILABLE(ios(10.0)) API_UNAVAILABLE(visionos, tvos) API_UNAVAILABLE(watchos) NS_SWIFT_UI_ACTOR
|
|
16
|
-
@interface UIFeedbackGenerator : NSObject
|
|
16
|
+
PEACH_SWIFT_CLASS(UIKitCore) @interface UIFeedbackGenerator : NSObject
|
|
17
17
|
|
|
18
18
|
/// initalize the generator with a view to attach it to the provided view as an interaction.
|
|
19
19
|
+ (instancetype)feedbackGeneratorForView:(UIView *)view NS_SWIFT_NAME(init(view:)) API_AVAILABLE(ios(17.5)) API_UNAVAILABLE(visionos);
|
package/sdk/ios/System/Library/Frameworks/UIKit.framework/Headers/UIImpactFeedbackGenerator.h
CHANGED
|
@@ -22,7 +22,7 @@ typedef NS_ENUM(NSInteger, UIImpactFeedbackStyle) {
|
|
|
22
22
|
|
|
23
23
|
// UIImpactFeedbackGenerator is used to give user feedback when an impact between UI elements occurs
|
|
24
24
|
UIKIT_EXTERN API_AVAILABLE(ios(10.0)) API_UNAVAILABLE(visionos, tvos) API_UNAVAILABLE(watchos) NS_SWIFT_UI_ACTOR
|
|
25
|
-
@interface UIImpactFeedbackGenerator : UIFeedbackGenerator
|
|
25
|
+
PEACH_SWIFT_CLASS(UIKitCore) @interface UIImpactFeedbackGenerator : UIFeedbackGenerator
|
|
26
26
|
|
|
27
27
|
/// set a style on the feedback generator and attach it to the provided view as an interaction.
|
|
28
28
|
+ (instancetype)feedbackGeneratorWithStyle:(UIImpactFeedbackStyle)style forView:(UIView *)view API_AVAILABLE(ios(17.5)) API_UNAVAILABLE(visionos) NS_SWIFT_NAME(init(style:view:));
|
|
@@ -16,7 +16,7 @@ typedef NSString * UINibOptionsKey NS_TYPED_ENUM API_UNAVAILABLE(watchos);
|
|
|
16
16
|
UIKIT_EXTERN UINibOptionsKey const UINibExternalObjects API_AVAILABLE(ios(3.0)) API_UNAVAILABLE(watchos);
|
|
17
17
|
|
|
18
18
|
@interface NSBundle(UINibLoadingAdditions)
|
|
19
|
-
- (nullable NSArray *)loadNibNamed:(NSString *)name owner:(nullable id)owner options:(nullable NSDictionary<UINibOptionsKey, id> *)options API_DEPRECATED("Loading Interface Builder products will not be supported in a future version of visionOS.", visionos(1.0, 1.0)) API_UNAVAILABLE(watchos);
|
|
19
|
+
- (nullable NSArray *)loadNibNamed:(NSString *)name owner:(nullable id)owner options:(nullable NSDictionary<UINibOptionsKey, id> *)options API_DEPRECATED("Loading Interface Builder products will not be supported in a future version of visionOS.", visionos(1.0, 1.0)) API_UNAVAILABLE(watchos) NS_SWIFT_UNAVAILABLE("UIKitCore declares Bundle.loadNibNamed(_:owner:options:)");
|
|
20
20
|
@end
|
|
21
21
|
|
|
22
22
|
@interface NSObject(UINibLoadingAdditions)
|
package/sdk/ios/System/Library/Frameworks/UIKit.framework/Headers/UINotificationFeedbackGenerator.h
CHANGED
|
@@ -18,7 +18,7 @@ typedef NS_ENUM(NSInteger, UINotificationFeedbackType) {
|
|
|
18
18
|
|
|
19
19
|
// UINotificationFeedbackGenerator is used to give user feedback when an notification is displayed
|
|
20
20
|
UIKIT_EXTERN API_AVAILABLE(ios(10.0)) API_UNAVAILABLE(visionos, tvos) API_UNAVAILABLE(watchos) NS_SWIFT_UI_ACTOR
|
|
21
|
-
@interface UINotificationFeedbackGenerator : UIFeedbackGenerator
|
|
21
|
+
PEACH_SWIFT_CLASS(UIKitCore) @interface UINotificationFeedbackGenerator : UIFeedbackGenerator
|
|
22
22
|
|
|
23
23
|
/// call when a notification is displayed, passing the corresponding type
|
|
24
24
|
- (void)notificationOccurred:(UINotificationFeedbackType)notificationType;
|
package/sdk/ios/System/Library/Frameworks/UIKit.framework/Headers/UISelectionFeedbackGenerator.h
CHANGED
|
@@ -12,7 +12,7 @@ NS_HEADER_AUDIT_BEGIN(nullability, sendability)
|
|
|
12
12
|
|
|
13
13
|
// UISelectionFeedbackGenerator is used to give user feedback when a selection changes
|
|
14
14
|
UIKIT_EXTERN API_AVAILABLE(ios(10.0)) API_UNAVAILABLE(visionos, tvos) API_UNAVAILABLE(watchos) NS_SWIFT_UI_ACTOR
|
|
15
|
-
@interface UISelectionFeedbackGenerator : UIFeedbackGenerator
|
|
15
|
+
PEACH_SWIFT_CLASS(UIKitCore) @interface UISelectionFeedbackGenerator : UIFeedbackGenerator
|
|
16
16
|
|
|
17
17
|
/// call when the selection changes (not on initial selection)
|
|
18
18
|
- (void)selectionChanged;
|
|
@@ -135,6 +135,13 @@ Protocols:
|
|
|
135
135
|
Tags:
|
|
136
136
|
- Name: _NSZone
|
|
137
137
|
SwiftName: _NSZone
|
|
138
|
+
Functions:
|
|
139
|
+
- Name: sel_registerName
|
|
140
|
+
NullabilityOfRet: N
|
|
141
|
+
Nullability: [N]
|
|
142
|
+
- Name: sel_getUid
|
|
143
|
+
NullabilityOfRet: N
|
|
144
|
+
Nullability: [N]
|
|
138
145
|
|
|
139
146
|
|
|
140
147
|
# Runtime functions did not yet have nullability in Swift 3.
|
package/src/android-theme.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// android theme resolution for a pure Kotlin app's window: app styles from the
|
|
1
|
+
// android theme resolution for a pure Kotlin app's window and default TextView: app styles from the
|
|
2
2
|
// module's res/values over the device's framework styles, resolved the way
|
|
3
3
|
// Resources.Theme does (explicit or dotted parents, `?attr` references,
|
|
4
4
|
// `@color` references). the framework half is generated from the platform's
|
|
@@ -11,16 +11,27 @@ export interface StyleValues {
|
|
|
11
11
|
items: Record<string, string>
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
// one item of a color state list file: the states it requires, its color and
|
|
15
|
+
// the alpha it multiplies in
|
|
16
|
+
export interface StateColorItem {
|
|
17
|
+
states: Partial<Record<string, boolean>>
|
|
18
|
+
color: string
|
|
19
|
+
alpha: string | null
|
|
20
|
+
}
|
|
21
|
+
|
|
14
22
|
// a values namespace: the framework's (`android:`) or the app's
|
|
15
23
|
export interface ResourceValues {
|
|
16
24
|
styles: Record<string, StyleValues>
|
|
17
25
|
colors: Record<string, string>
|
|
26
|
+
dimens: Record<string, string>
|
|
27
|
+
// res/color state lists by name
|
|
28
|
+
stateColors: Record<string, StateColorItem[]>
|
|
18
29
|
}
|
|
19
30
|
|
|
20
31
|
export function readResourceValues(
|
|
21
32
|
files: Array<{ file: string; text: string }>,
|
|
22
33
|
): ResourceValues {
|
|
23
|
-
const values: ResourceValues = { styles: {}, colors: {} }
|
|
34
|
+
const values: ResourceValues = { styles: {}, colors: {}, dimens: {}, stateColors: {} }
|
|
24
35
|
for (const { file, text } of files) {
|
|
25
36
|
for (const resources of parseXml(text, file).children) {
|
|
26
37
|
if (resources.name !== 'resources') continue
|
|
@@ -28,6 +39,11 @@ export function readResourceValues(
|
|
|
28
39
|
const name = entry.attributes.name
|
|
29
40
|
if (!name) continue
|
|
30
41
|
if (entry.name === 'color') values.colors[name] = entry.text.trim()
|
|
42
|
+
if (
|
|
43
|
+
entry.name === 'dimen' ||
|
|
44
|
+
(entry.name === 'item' && entry.attributes.type === 'dimen')
|
|
45
|
+
)
|
|
46
|
+
values.dimens[name] = entry.text.trim()
|
|
31
47
|
if (entry.name !== 'style') continue
|
|
32
48
|
const items: Record<string, string> = {}
|
|
33
49
|
for (const item of entry.children)
|
|
@@ -203,3 +219,121 @@ export function attributeColor(value: string, sources: ThemeSources): number {
|
|
|
203
219
|
if (!ref) throw new Error(`the color ${value} is not resolved by Peach yet`)
|
|
204
220
|
return resourceColor(ref.namespace, ref.name, sources)
|
|
205
221
|
}
|
|
222
|
+
|
|
223
|
+
// a res/color selector as ColorStateList.inflate reads it
|
|
224
|
+
export function readColorStateList(text: string, file: string): StateColorItem[] {
|
|
225
|
+
const selector = parseXml(text, file).children.find(
|
|
226
|
+
(child) => child.name === 'selector',
|
|
227
|
+
)
|
|
228
|
+
if (!selector) throw new Error(`${file}: not a color state list`)
|
|
229
|
+
return selector.children
|
|
230
|
+
.filter((item) => item.name === 'item')
|
|
231
|
+
.map((item) => {
|
|
232
|
+
const states: Record<string, boolean> = {}
|
|
233
|
+
for (const [key, value] of Object.entries(item.attributes))
|
|
234
|
+
if (key.startsWith('android:state_')) states[key.slice(8)] = value === 'true'
|
|
235
|
+
const color = item.attributes['android:color']
|
|
236
|
+
if (!color) throw new Error(`${file}: an item has no android:color`)
|
|
237
|
+
return { states, color, alpha: item.attributes['android:alpha'] ?? null }
|
|
238
|
+
})
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// TextView's default color and size under a theme
|
|
242
|
+
export interface TextAppearance {
|
|
243
|
+
color: number
|
|
244
|
+
// a dimension as written: `14sp`, `16dp` or `15px`
|
|
245
|
+
size: string
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
type Found = { value: string; namespace: Namespace }
|
|
249
|
+
|
|
250
|
+
// what TextView's constructor reads when a layout sets neither: the
|
|
251
|
+
// textAppearance its textViewStyle or the theme names, then a textColor or
|
|
252
|
+
// textSize the style or the theme sets itself. with none, TextView's own
|
|
253
|
+
// black and 15px.
|
|
254
|
+
export function resolveTextAppearance(
|
|
255
|
+
theme: string,
|
|
256
|
+
sources: ThemeSources,
|
|
257
|
+
): TextAppearance {
|
|
258
|
+
const themeChain = styleChain(styleRef(theme, 'app'), sources)
|
|
259
|
+
const android = (name: string) => ({ namespace: 'android' as const, name })
|
|
260
|
+
// follows `?attr` references through the theme
|
|
261
|
+
const resolve = (start: Found): Found => {
|
|
262
|
+
const seen = new Set<string>()
|
|
263
|
+
let found = start
|
|
264
|
+
for (;;) {
|
|
265
|
+
const attr = /^\?(?:(android):)?(?:attr\/)?(.+)$/.exec(found.value)
|
|
266
|
+
if (!attr?.[2]) return found
|
|
267
|
+
if (seen.has(`${found.namespace}:${found.value}`))
|
|
268
|
+
throw new Error(`${theme}: ${found.value} refers to itself`)
|
|
269
|
+
seen.add(`${found.namespace}:${found.value}`)
|
|
270
|
+
const next = lookup(themeChain, {
|
|
271
|
+
namespace: attr[1] ? 'android' : found.namespace,
|
|
272
|
+
name: attr[2],
|
|
273
|
+
})
|
|
274
|
+
if (!next) throw new Error(`${theme}: ${found.value} is not set`)
|
|
275
|
+
found = next
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
const style = (found: Found | null) => {
|
|
279
|
+
if (!found) return []
|
|
280
|
+
const { value, namespace } = resolve(found)
|
|
281
|
+
return styleChain(styleRef(value, namespace), sources)
|
|
282
|
+
}
|
|
283
|
+
const dimen = (found: Found): string => {
|
|
284
|
+
let { value, namespace } = resolve(found)
|
|
285
|
+
const seen = new Set<string>()
|
|
286
|
+
for (;;) {
|
|
287
|
+
const ref = /^@(?:(android):)?dimen\/(.+)$/.exec(value)
|
|
288
|
+
if (!ref?.[2]) return value
|
|
289
|
+
if (seen.has(value)) throw new Error(`${theme}: ${value} refers to itself`)
|
|
290
|
+
seen.add(value)
|
|
291
|
+
namespace = ref[1] ? 'android' : namespace
|
|
292
|
+
const next = sources[namespace].dimens[ref[2]]
|
|
293
|
+
if (next === undefined)
|
|
294
|
+
throw new Error(`@${namespace}:dimen/${ref[2]} is not defined`)
|
|
295
|
+
value = next
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// a color or the color an enabled view in no other state takes from a
|
|
299
|
+
// state list, its alpha modulated as ColorStateList.modulateColor does
|
|
300
|
+
const colorOf = (found: Found): number => {
|
|
301
|
+
const { value, namespace } = resolve(found)
|
|
302
|
+
if (value.startsWith('#')) return color(value)
|
|
303
|
+
const ref = colorReference(value, namespace)
|
|
304
|
+
if (!ref)
|
|
305
|
+
throw new Error(`${theme}: the text color ${value} is not resolved by Peach yet`)
|
|
306
|
+
const list = sources[ref.namespace].stateColors[ref.name]
|
|
307
|
+
if (!list) return resourceColor(ref.namespace, ref.name, sources)
|
|
308
|
+
const item = list.find((entry) =>
|
|
309
|
+
Object.entries(entry.states).every(
|
|
310
|
+
([state, on]) => on === (state === 'state_enabled'),
|
|
311
|
+
),
|
|
312
|
+
)
|
|
313
|
+
if (!item) throw new Error(`@${ref.namespace}:color/${ref.name} has no enabled item`)
|
|
314
|
+
const base = colorOf({ value: item.color, namespace: ref.namespace })
|
|
315
|
+
if (item.alpha === null) return base
|
|
316
|
+
const alphaMod = Number(dimen({ value: item.alpha, namespace: ref.namespace }))
|
|
317
|
+
if (!Number.isFinite(alphaMod))
|
|
318
|
+
throw new Error(
|
|
319
|
+
`@${ref.namespace}:color/${ref.name}: unreadable alpha ${item.alpha}`,
|
|
320
|
+
)
|
|
321
|
+
const alpha = Math.min(255, Math.max(0, Math.trunc((base >>> 24) * alphaMod + 0.5)))
|
|
322
|
+
return ((alpha << 24) | (base & 0xffffff)) >>> 0
|
|
323
|
+
}
|
|
324
|
+
const textViewStyle = style(lookup(themeChain, android('textViewStyle')))
|
|
325
|
+
const appearance = style(
|
|
326
|
+
lookup(textViewStyle, android('textAppearance')) ??
|
|
327
|
+
lookup(themeChain, android('textAppearance')),
|
|
328
|
+
)
|
|
329
|
+
const attribute = (name: string) =>
|
|
330
|
+
lookup(textViewStyle, android(name)) ??
|
|
331
|
+
lookup(themeChain, android(name)) ??
|
|
332
|
+
lookup(appearance, android(name))
|
|
333
|
+
const textColor = attribute('textColor')
|
|
334
|
+
const textSize = attribute('textSize')
|
|
335
|
+
const size = textSize ? dimen(textSize) : '15px'
|
|
336
|
+
if (!/^\d+(?:\.\d+)?(?:sp|dp|dip|px)$/.test(size))
|
|
337
|
+
throw new Error(`${theme}: the text size ${size} is not resolved by Peach yet`)
|
|
338
|
+
return { color: textColor ? colorOf(textColor) : 0xff000000, size }
|
|
339
|
+
}
|
package/src/expo-swift-host.ts
CHANGED
|
@@ -1020,6 +1020,88 @@ function enrichInstalledUnits(
|
|
|
1020
1020
|
for (const unit of units) unit.nativeFiles = { ...unit.nativeFiles, ...support }
|
|
1021
1021
|
}
|
|
1022
1022
|
|
|
1023
|
+
// Swift compiled without the pod's Objective-C still names those classes.
|
|
1024
|
+
// A requester keeps the protocol its header declares, so the generic
|
|
1025
|
+
// constraint can infer. The prepared workspace compiles the real .m files.
|
|
1026
|
+
function swiftAloneObjCClasses(
|
|
1027
|
+
ios: string,
|
|
1028
|
+
swift: string,
|
|
1029
|
+
resolveSource: (file: string) => string,
|
|
1030
|
+
): string | null {
|
|
1031
|
+
if (!fs.existsSync(ios)) return null
|
|
1032
|
+
const interfaces = new Map<string, { superName?: string; protocols: string[] }>()
|
|
1033
|
+
const visit = (dir: string) => {
|
|
1034
|
+
for (const child of fs.readdirSync(resolveSource(dir), { withFileTypes: true })) {
|
|
1035
|
+
if (
|
|
1036
|
+
child.name.startsWith('.') ||
|
|
1037
|
+
child.name === 'build' ||
|
|
1038
|
+
child.name === 'node_modules' ||
|
|
1039
|
+
/\.(?:xcframework|framework)$/.test(child.name)
|
|
1040
|
+
)
|
|
1041
|
+
continue
|
|
1042
|
+
const file = path.join(dir, child.name)
|
|
1043
|
+
const resolved = resolveSource(file)
|
|
1044
|
+
const stat = fs.statSync(resolved)
|
|
1045
|
+
if (stat.isDirectory()) {
|
|
1046
|
+
visit(file)
|
|
1047
|
+
continue
|
|
1048
|
+
}
|
|
1049
|
+
if (!stat.isFile() || !child.name.endsWith('.h')) continue
|
|
1050
|
+
const text = fs.readFileSync(resolved, 'utf8')
|
|
1051
|
+
for (const match of text.matchAll(
|
|
1052
|
+
/@interface\s+(\w+)\s*(\([^)\n]*\))?\s*(?::\s*(\w+))?\s*(?:<([^>\n]+)>)?/g,
|
|
1053
|
+
)) {
|
|
1054
|
+
if (match[2]) continue
|
|
1055
|
+
interfaces.set(match[1]!, {
|
|
1056
|
+
...(match[3] ? { superName: match[3] } : {}),
|
|
1057
|
+
protocols: (match[4] ?? '')
|
|
1058
|
+
.split(',')
|
|
1059
|
+
.map((name) => name.trim())
|
|
1060
|
+
.filter((name) => name.length > 0),
|
|
1061
|
+
})
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
visit(ios)
|
|
1066
|
+
if (interfaces.size === 0) return null
|
|
1067
|
+
const code = swiftCodeMask(swift)
|
|
1068
|
+
const declared = new Set(
|
|
1069
|
+
[
|
|
1070
|
+
...code.matchAll(
|
|
1071
|
+
/\b(?:class|struct|enum|protocol|actor|typealias)\s+([A-Za-z_]\w*)/g,
|
|
1072
|
+
),
|
|
1073
|
+
].map((match) => match[1]!),
|
|
1074
|
+
)
|
|
1075
|
+
const referenced = new Set(code.match(/[A-Za-z_]\w*/g) ?? [])
|
|
1076
|
+
const needed = [...interfaces.keys()]
|
|
1077
|
+
.filter((name) => referenced.has(name) && !declared.has(name))
|
|
1078
|
+
.sort()
|
|
1079
|
+
if (needed.length === 0) return null
|
|
1080
|
+
const protocolsOf = (name: string, seen = new Set<string>()): string[] => {
|
|
1081
|
+
if (seen.has(name)) return []
|
|
1082
|
+
seen.add(name)
|
|
1083
|
+
const item = interfaces.get(name)
|
|
1084
|
+
if (!item) return []
|
|
1085
|
+
return [
|
|
1086
|
+
...item.protocols,
|
|
1087
|
+
...(item.superName ? protocolsOf(item.superName, seen) : []),
|
|
1088
|
+
]
|
|
1089
|
+
}
|
|
1090
|
+
const classes = needed.map((name) => {
|
|
1091
|
+
if (!new Set(protocolsOf(name)).has('EXPermissionsRequester'))
|
|
1092
|
+
return `public class ${name}: NSObject {}`
|
|
1093
|
+
return `public class ${name}: NSObject, EXPermissionsRequester {
|
|
1094
|
+
public static func permissionType() -> String { "" }
|
|
1095
|
+
public func getPermissions() -> [AnyHashable: Any] { [:] }
|
|
1096
|
+
public func requestPermissions(
|
|
1097
|
+
resolver resolve: @escaping EXPromiseResolveBlock,
|
|
1098
|
+
rejecter reject: @escaping EXPromiseRejectBlock
|
|
1099
|
+
) {}
|
|
1100
|
+
}`
|
|
1101
|
+
})
|
|
1102
|
+
return `import ExpoModulesCore\nimport Foundation\n\n${classes.join('\n\n')}\n`
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1023
1105
|
export async function collectExpoSwiftSources(
|
|
1024
1106
|
appRoot: string,
|
|
1025
1107
|
signal?: AbortSignal,
|
|
@@ -1580,10 +1662,17 @@ async function collectExpoSwiftSourcesUncached(
|
|
|
1580
1662
|
walkFrameworks(canonical)
|
|
1581
1663
|
// this path compiles Swift alone; the report names the cause when a
|
|
1582
1664
|
// Swift file then fails on the pod's own Objective-C or C types.
|
|
1583
|
-
if (nativeSources.size > 0 && !prepareNative && !metadataOnly)
|
|
1665
|
+
if (nativeSources.size > 0 && !prepareNative && !metadataOnly) {
|
|
1584
1666
|
report(
|
|
1585
1667
|
`${packageName}: ${namespace} has Objective-C or C sources (${[...nativeSources].sort()[0]}), which compile only from a CocoaPods workspace a Mac prepares; compiling its Swift alone`,
|
|
1586
1668
|
)
|
|
1669
|
+
const surface = swiftAloneObjCClasses(
|
|
1670
|
+
ios,
|
|
1671
|
+
Object.values(files).join('\n'),
|
|
1672
|
+
resolveSource,
|
|
1673
|
+
)
|
|
1674
|
+
if (surface) files[`Sources/${namespace}/PeachObjCSurface.swift`] = surface
|
|
1675
|
+
}
|
|
1587
1676
|
}
|
|
1588
1677
|
// a module compiled from its own source declares its iOS floor in its
|
|
1589
1678
|
// podspec; CocoaPods builds the pod at that floor.
|