peachsim 0.1.2198 → 0.1.2200
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/cli/commands/inspect/settling.ts +20 -20
- package/cli/outbound-endpoints.ts +12 -0
- 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 +1532 -1170
- 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 +22 -22
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/expo-swift-bundle.cjs +45875 -39899
- 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 +50942 -49780
- package/dist-lib/host/fetch-proxy-handler.cjs +16 -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 +36 -24
- 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 +100 -10
- 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 +16 -4
- package/dist-lib/native-app-identity-project.cjs +14 -2
- package/dist-lib/native-app-identity-project.mjs +14 -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 +302 -289
- 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 +21 -21
- package/dist-lib/sdk.mjs +21 -21
- package/dist-lib/skills.cjs +3622 -2962
- package/dist-lib/swift-compile.cjs +34 -3
- package/dist-lib/swift-compile.mjs +34 -3
- 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 +129 -43
- package/dist-lib/vite.cjs +16 -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/scene-table.d.ts +2 -0
- package/dist-types/packages/peach-engine/src/render-worker/app-prefetch-contract.d.ts +5 -0
- package/dist-types/packages/peach-engine/src/render-worker/protocol.d.ts +2 -0
- package/dist-types/packages/peach-engine/src/render-worker/tree-sync-port.d.ts +5 -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/Foundation.h +2 -0
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSBundle.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSByteCountFormatter.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSCharacterSet.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSCompoundPredicate.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSDateIntervalFormatter.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSDecimalNumber.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSEnergyFormatter.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/NSFileHandle.h +2 -2
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSISO8601DateFormatter.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSIndexSet.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSLengthFormatter.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSLock.h +3 -3
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSMassFormatter.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSMeasurementFormatter.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSNotification.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSNotificationQueue.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h +4 -0
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSOrthography.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSScanner.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSThread.h +1 -1
- package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSUnit.h +25 -25
- package/sdk/ios/System/Library/Frameworks/QuartzCore.framework/Headers/CAValueFunction.h +1 -1
- package/sdk/ios/System/Library/Frameworks/QuartzCore.framework/Headers/CoreAnimation.h +1 -0
- package/sdk/ios/System/Library/Frameworks/QuartzCore.framework/Modules/module.modulemap +1 -0
- package/sdk/ios/System/Library/Frameworks/UIKitText.framework/Headers/UIKitText.apinotes +14 -0
- package/src/android-layout-ids.ts +50 -0
- package/src/android-view-classes.ts +41 -0
- package/src/expo-native-workspace.ts +2 -3
- package/src/expo-swift-host.ts +6 -1
- package/src/java-module-abi.ts +2 -0
- package/src/javaAbiContract.ts +2 -0
- package/src/kotlin-app.ts +33 -7
- package/src/kotlin-host.ts +83 -6
- package/src/kotlin-maven-sources.ts +248 -0
- package/src/native-prebuilt.ts +36 -2
- package/src/native-swift-slices.ts +43 -2
- package/src/react-native-bridge-modules.ts +7 -1
- package/src/react-native-core-build.ts +176 -0
- package/src/react-native-core-digest.ts +1 -1
- package/src/react-native-core.ts +24 -7
- package/src/swift-packages.ts +3 -0
- package/src/swift-standin-emit.ts +9 -1
- package/src/swift-standins.ts +5 -2
- package/src/swift-wasm-prune.ts +41 -3
- package/src/turbo-compile.ts +2 -1
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
#import <QuartzCore/CAEmitterCell.h>
|
|
15
15
|
#import <QuartzCore/CAEmitterLayer.h>
|
|
16
16
|
#import <QuartzCore/CAGradientLayer.h>
|
|
17
|
+
#import <QuartzCore/CAMetalLayer.h>
|
|
17
18
|
#import <QuartzCore/CAReplicatorLayer.h>
|
|
18
19
|
#import <QuartzCore/CAScrollLayer.h>
|
|
19
20
|
#import <QuartzCore/CAShapeLayer.h>
|
|
@@ -81,6 +81,20 @@ Tags:
|
|
|
81
81
|
Typedefs:
|
|
82
82
|
- Name: NSTextListMarkerFormat
|
|
83
83
|
SwiftName: NSTextList.MarkerFormat
|
|
84
|
+
- Name: NSAttributedStringDocumentAttributeKey
|
|
85
|
+
SwiftName: NSAttributedString.DocumentAttributeKey
|
|
86
|
+
- Name: NSAttributedStringDocumentReadingOptionKey
|
|
87
|
+
SwiftName: NSAttributedString.DocumentReadingOptionKey
|
|
88
|
+
- Name: NSAttributedStringDocumentType
|
|
89
|
+
SwiftName: NSAttributedString.DocumentType
|
|
90
|
+
- Name: NSTextEffectStyle
|
|
91
|
+
SwiftName: NSAttributedString.TextEffectStyle
|
|
92
|
+
- Name: NSTextHighlightStyle
|
|
93
|
+
SwiftName: NSAttributedString.TextHighlightStyle
|
|
94
|
+
- Name: NSTextHighlightColorScheme
|
|
95
|
+
SwiftName: NSAttributedString.TextHighlightColorScheme
|
|
96
|
+
- Name: NSTextLayoutSectionKey
|
|
97
|
+
SwiftName: NSAttributedString.TextLayoutSectionKey
|
|
84
98
|
- Name: NSTextTabOptionKey
|
|
85
99
|
SwiftName: NSTextTab.OptionKey
|
|
86
100
|
- Name: UIFontDescriptorAttributeName
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { parseXml, type XmlElement } from './android-xml'
|
|
4
|
+
|
|
5
|
+
// the layout names and view ids a module's R class declares: every layout
|
|
6
|
+
// file's name, every `@+id/` or `@id/` an attribute names in a layout, and each
|
|
7
|
+
// `<item type="id">` in values, as aapt2 declares them
|
|
8
|
+
export interface AndroidLayoutIds {
|
|
9
|
+
layouts: string[]
|
|
10
|
+
ids: string[]
|
|
11
|
+
// the unqualified `layout` directory's files by name, which Resources inflates
|
|
12
|
+
elements: Map<string, XmlElement>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const LAYOUT_DIR = /^layout(?:-[A-Za-z0-9+-]+)?$/
|
|
16
|
+
const ID_REFERENCE = /@\+?id\/([A-Za-z0-9_.]+)/g
|
|
17
|
+
const ID_ITEM = /<item\b[^>]*\btype\s*=\s*"id"[^>]*>/g
|
|
18
|
+
const ITEM_NAME = /\bname\s*=\s*"([^"]+)"/
|
|
19
|
+
|
|
20
|
+
export function readAndroidLayoutIds(moduleDir: string): AndroidLayoutIds {
|
|
21
|
+
const res = path.join(moduleDir, 'src/main/res')
|
|
22
|
+
const layouts = new Set<string>()
|
|
23
|
+
const ids = new Set<string>()
|
|
24
|
+
const elements = new Map<string, XmlElement>()
|
|
25
|
+
for (const dir of fs.existsSync(res) ? fs.readdirSync(res).sort() : []) {
|
|
26
|
+
const directory = path.join(res, dir)
|
|
27
|
+
if (LAYOUT_DIR.test(dir)) {
|
|
28
|
+
for (const entry of fs.readdirSync(directory).sort()) {
|
|
29
|
+
if (!entry.endsWith('.xml')) continue
|
|
30
|
+
layouts.add(entry.slice(0, -'.xml'.length))
|
|
31
|
+
const xml = fs.readFileSync(path.join(directory, entry), 'utf8')
|
|
32
|
+
for (const match of xml.matchAll(ID_REFERENCE)) ids.add(match[1])
|
|
33
|
+
if (dir === 'layout') {
|
|
34
|
+
const root = parseXml(xml, path.join(directory, entry)).children[0]
|
|
35
|
+
if (root) elements.set(entry.slice(0, -'.xml'.length), root)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
} else if (dir.startsWith('values')) {
|
|
39
|
+
for (const entry of fs.readdirSync(directory).sort()) {
|
|
40
|
+
if (!entry.endsWith('.xml')) continue
|
|
41
|
+
const xml = fs.readFileSync(path.join(directory, entry), 'utf8')
|
|
42
|
+
for (const item of xml.matchAll(ID_ITEM)) {
|
|
43
|
+
const name = ITEM_NAME.exec(item[0])?.[1]
|
|
44
|
+
if (name) ids.add(name)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return { layouts: [...layouts].sort(), ids: [...ids].sort(), elements }
|
|
50
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { XmlElement } from './android-xml'
|
|
2
|
+
|
|
3
|
+
// the framework view classes LayoutInflater can create; each is a Kotlin class
|
|
4
|
+
// of the same name in AndroidViewSources, linked into an app only when one of
|
|
5
|
+
// its layouts names it
|
|
6
|
+
export const androidViewClasses = [
|
|
7
|
+
'android.view.View',
|
|
8
|
+
'android.widget.FrameLayout',
|
|
9
|
+
'android.widget.ImageView',
|
|
10
|
+
'android.widget.LinearLayout',
|
|
11
|
+
'android.widget.RelativeLayout',
|
|
12
|
+
'android.widget.TextView',
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
// PhoneLayoutInflater's prefixes, then LayoutInflater's own
|
|
16
|
+
const classPrefixes = [
|
|
17
|
+
'android.widget.',
|
|
18
|
+
'android.webkit.',
|
|
19
|
+
'android.app.',
|
|
20
|
+
'android.view.',
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
// the classes a set of layout trees names, as the inflater resolves a tag: a
|
|
24
|
+
// dotted name is that class, any other tries each framework prefix in order
|
|
25
|
+
export function layoutViewClasses(roots: Iterable<XmlElement>): string[] {
|
|
26
|
+
const used = new Set<string>()
|
|
27
|
+
const visit = (element: XmlElement) => {
|
|
28
|
+
if (element.name !== 'include' && element.name !== 'merge') {
|
|
29
|
+
if (element.name.includes('.')) used.add(element.name)
|
|
30
|
+
else {
|
|
31
|
+
const found = classPrefixes
|
|
32
|
+
.map((prefix) => prefix + element.name)
|
|
33
|
+
.find((name) => androidViewClasses.includes(name))
|
|
34
|
+
if (found) used.add(found)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
element.children.forEach(visit)
|
|
38
|
+
}
|
|
39
|
+
for (const root of roots) visit(root)
|
|
40
|
+
return [...used].sort()
|
|
41
|
+
}
|
|
@@ -744,7 +744,7 @@ function trackedSourceEntries(root: string, work: string): string[] {
|
|
|
744
744
|
function initializeWorkspaceGit(root: string, work: string) {
|
|
745
745
|
requireNativeGit()
|
|
746
746
|
const env = { ...process.env, ...isolatedGitEnv }
|
|
747
|
-
execFileSync('git', ['init', '--quiet'], { cwd: work, env
|
|
747
|
+
execFileSync('git', ['init', '--quiet'], { cwd: work, env })
|
|
748
748
|
execFileSync(
|
|
749
749
|
'git',
|
|
750
750
|
[
|
|
@@ -761,7 +761,7 @@ function initializeWorkspaceGit(root: string, work: string) {
|
|
|
761
761
|
'-m',
|
|
762
762
|
'prepared workspace',
|
|
763
763
|
],
|
|
764
|
-
{ cwd: work, env
|
|
764
|
+
{ cwd: work, env },
|
|
765
765
|
)
|
|
766
766
|
const tracked = trackedSourceEntries(root, work)
|
|
767
767
|
if (tracked.length > 0)
|
|
@@ -769,7 +769,6 @@ function initializeWorkspaceGit(root: string, work: string) {
|
|
|
769
769
|
cwd: work,
|
|
770
770
|
env,
|
|
771
771
|
input: tracked.join('\0'),
|
|
772
|
-
timeout: 60_000,
|
|
773
772
|
})
|
|
774
773
|
}
|
|
775
774
|
|
package/src/expo-swift-host.ts
CHANGED
|
@@ -2353,7 +2353,12 @@ async function compileExpoSwiftModulesTraced(
|
|
|
2353
2353
|
'react-native/package.json',
|
|
2354
2354
|
),
|
|
2355
2355
|
)
|
|
2356
|
-
const provider = prebuiltReactNativeCore(
|
|
2356
|
+
const provider = await prebuiltReactNativeCore(
|
|
2357
|
+
projectRoot,
|
|
2358
|
+
reactNativeRoot,
|
|
2359
|
+
module.root,
|
|
2360
|
+
'expo',
|
|
2361
|
+
)
|
|
2357
2362
|
const headers = new Map<string, { file: string; relative: string }[]>()
|
|
2358
2363
|
for (const [file, body] of Object.entries(provider.files)) {
|
|
2359
2364
|
const relative = file.split('/upstream/react-native/')[1]
|
package/src/java-module-abi.ts
CHANGED
|
@@ -62,6 +62,7 @@ export async function readJavaModuleSpecs(
|
|
|
62
62
|
typeof row.className !== 'string' ||
|
|
63
63
|
(row.name !== null && typeof row.name !== 'string') ||
|
|
64
64
|
typeof row.source !== 'string' ||
|
|
65
|
+
(row.application !== undefined && typeof row.application !== 'boolean') ||
|
|
65
66
|
!Array.isArray(row.methods)
|
|
66
67
|
)
|
|
67
68
|
throw new Error('Java module reader printed an invalid spec')
|
|
@@ -73,6 +74,7 @@ export async function readJavaModuleSpecs(
|
|
|
73
74
|
name: row.name,
|
|
74
75
|
source: row.source,
|
|
75
76
|
methods: row.methods.map(readBridgeMethod),
|
|
77
|
+
application: row.application === true,
|
|
76
78
|
}
|
|
77
79
|
})
|
|
78
80
|
return { sha256: digest.digest('hex'), specs }
|
package/src/javaAbiContract.ts
CHANGED
package/src/kotlin-app.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import fs from 'node:fs'
|
|
7
7
|
import path from 'node:path'
|
|
8
8
|
import { readAndroidDrawables, type AndroidDrawable } from './android-drawables'
|
|
9
|
+
import { readAndroidLayoutIds, type AndroidLayoutIds } from './android-layout-ids'
|
|
9
10
|
import { readAndroidStrings, type AndroidStringResources } from './android-strings'
|
|
10
11
|
import {
|
|
11
12
|
readResourceValues,
|
|
@@ -18,6 +19,7 @@ import { parseXml, type XmlElement } from './android-xml'
|
|
|
18
19
|
import frameworkThemes from './generated/android-framework-themes.json' with { type: 'json' }
|
|
19
20
|
import { isRecord } from './is-record'
|
|
20
21
|
import { composeBomVersions } from './kotlin-compose-bom'
|
|
22
|
+
import { mavenKotlinSources } from './kotlin-maven-sources'
|
|
21
23
|
import { KotlinVersionCatalog } from './kotlin-version-catalog'
|
|
22
24
|
import type { AndroidGradleDependency } from './androidGradleContract'
|
|
23
25
|
|
|
@@ -60,6 +62,7 @@ export interface KotlinAppProject {
|
|
|
60
62
|
strings: AndroidStringResources
|
|
61
63
|
colors: KotlinAppColor[]
|
|
62
64
|
drawables: AndroidDrawable[]
|
|
65
|
+
layoutIds: AndroidLayoutIds
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
// a color resource's ARGB in the day and the night configuration
|
|
@@ -244,6 +247,7 @@ function kotlinPluginVersion(
|
|
|
244
247
|
}
|
|
245
248
|
|
|
246
249
|
async function checkModuleGradle(
|
|
250
|
+
projectDir: string,
|
|
247
251
|
gradle: { file: string; text: string },
|
|
248
252
|
pins: AndroidPins,
|
|
249
253
|
catalog: KotlinVersionCatalog,
|
|
@@ -258,7 +262,7 @@ async function checkModuleGradle(
|
|
|
258
262
|
throw new Error(`${where}: ${value} is not a literal or catalog dependency`)
|
|
259
263
|
}
|
|
260
264
|
const platforms = new Map<string, string>()
|
|
261
|
-
const dependencies: { coordinate: string; where: string }[] = []
|
|
265
|
+
const dependencies: { coordinate: string; where: string; compile: boolean }[] = []
|
|
262
266
|
let usesSerialization = false
|
|
263
267
|
for (const match of gradle.text.matchAll(
|
|
264
268
|
/\bid\(\s*"([^"]+)"\s*\)|\bkotlin\(\s*"([^"]+)"\s*\)|\balias\(\s*libs\.plugins\.([\w.]+)\s*\)/g,
|
|
@@ -291,6 +295,7 @@ async function checkModuleGradle(
|
|
|
291
295
|
dependencies.push({
|
|
292
296
|
coordinate: `${dependency.group}:${dependency.name}:${dependency.version}`,
|
|
293
297
|
where: gradle.file,
|
|
298
|
+
compile: true,
|
|
294
299
|
})
|
|
295
300
|
}
|
|
296
301
|
} else
|
|
@@ -321,6 +326,10 @@ async function checkModuleGradle(
|
|
|
321
326
|
if (!call) throw new Error(`${where}: ${text} is not a literal dependency`)
|
|
322
327
|
const [, configuration = '', value = ''] = call
|
|
323
328
|
if (/^(test|androidTest|debug|release)/.test(configuration)) continue
|
|
329
|
+
const compile =
|
|
330
|
+
configuration === 'implementation' ||
|
|
331
|
+
configuration === 'api' ||
|
|
332
|
+
configuration === 'compileOnly'
|
|
324
333
|
const platform = /^platform\(\s*(.*?)\s*\)$/.exec(
|
|
325
334
|
platformVariables.get(value) ?? value,
|
|
326
335
|
)
|
|
@@ -338,11 +347,13 @@ async function checkModuleGradle(
|
|
|
338
347
|
}
|
|
339
348
|
} else {
|
|
340
349
|
for (const coordinate of coordinates(value, where))
|
|
341
|
-
dependencies.push({ coordinate, where })
|
|
350
|
+
dependencies.push({ coordinate, where, compile })
|
|
342
351
|
}
|
|
343
352
|
}
|
|
344
353
|
}
|
|
345
|
-
|
|
354
|
+
const librarySources: string[] = []
|
|
355
|
+
const seen = new Set<string>()
|
|
356
|
+
for (const { coordinate, where, compile } of dependencies) {
|
|
346
357
|
const parts = /^([^:]+):([^:]+)(?::([^:]+))?$/.exec(coordinate)
|
|
347
358
|
if (!parts)
|
|
348
359
|
throw new Error(`${where}: ${coordinate} is not a group:artifact[:version]`)
|
|
@@ -361,10 +372,22 @@ async function checkModuleGradle(
|
|
|
361
372
|
throw new Error(
|
|
362
373
|
`${where}: ${name}:${version} differs from Peach's ${pin} pin ${pins[pin]}`,
|
|
363
374
|
)
|
|
364
|
-
} else if (!PLATFORM_GROUPS.has(group) && !PLATFORM_ARTIFACTS.has(name))
|
|
365
|
-
|
|
375
|
+
} else if (!PLATFORM_GROUPS.has(group) && !PLATFORM_ARTIFACTS.has(name)) {
|
|
376
|
+
const sources = compile
|
|
377
|
+
? await mavenKotlinSources(projectDir, { group, artifact, version }, where)
|
|
378
|
+
: null
|
|
379
|
+
if (!sources)
|
|
380
|
+
throw new Error(
|
|
381
|
+
`${where}: ${group}:${artifact}:${version} is not in Peach's Kotlin closure`,
|
|
382
|
+
)
|
|
383
|
+
for (const file of sources) {
|
|
384
|
+
if (seen.has(file)) continue
|
|
385
|
+
seen.add(file)
|
|
386
|
+
librarySources.push(file)
|
|
387
|
+
}
|
|
388
|
+
}
|
|
366
389
|
}
|
|
367
|
-
return { usesSerialization }
|
|
390
|
+
return { usesSerialization, librarySources }
|
|
368
391
|
}
|
|
369
392
|
|
|
370
393
|
// Resources.selectDefaultTheme: the theme a context without one gets for its
|
|
@@ -566,7 +589,8 @@ export async function readKotlinApp(
|
|
|
566
589
|
targetSdk: model.targetSdk,
|
|
567
590
|
}
|
|
568
591
|
})()
|
|
569
|
-
const { usesSerialization } = await checkModuleGradle(
|
|
592
|
+
const { usesSerialization, librarySources } = await checkModuleGradle(
|
|
593
|
+
projectDir,
|
|
570
594
|
gradle,
|
|
571
595
|
options.pins,
|
|
572
596
|
catalog,
|
|
@@ -729,6 +753,7 @@ export async function readKotlinApp(
|
|
|
729
753
|
}
|
|
730
754
|
walk(dir)
|
|
731
755
|
}
|
|
756
|
+
sources.push(...librarySources)
|
|
732
757
|
if (sources.length === 0)
|
|
733
758
|
throw new Error(`${moduleDir}/src/main holds no Kotlin sources`)
|
|
734
759
|
const resources = {
|
|
@@ -757,5 +782,6 @@ export async function readKotlinApp(
|
|
|
757
782
|
strings: readAndroidStrings(moduleDir),
|
|
758
783
|
colors: readAppColors(moduleDir, resources),
|
|
759
784
|
drawables: readAndroidDrawables(moduleDir, resources),
|
|
785
|
+
layoutIds: readAndroidLayoutIds(moduleDir),
|
|
760
786
|
}
|
|
761
787
|
}
|
package/src/kotlin-host.ts
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
type BridgeModule,
|
|
19
19
|
type BridgeSelection,
|
|
20
20
|
} from './android-bridge-packages'
|
|
21
|
+
import { layoutViewClasses } from './android-view-classes'
|
|
21
22
|
import { rnxHomeDir } from './home-paths'
|
|
22
23
|
import { isRecord } from './is-record'
|
|
23
24
|
import {
|
|
@@ -39,6 +40,7 @@ import {
|
|
|
39
40
|
type ViewModelClass,
|
|
40
41
|
} from './kotlin-view-models'
|
|
41
42
|
import type { DayNight, DrawableFile } from './android-drawables'
|
|
43
|
+
import type { XmlElement } from './android-xml'
|
|
42
44
|
import type { ExpoKotlinModules } from './expo-kotlin-host'
|
|
43
45
|
import type { KotlinAppProject, KotlinWindowTheme } from './kotlin-app'
|
|
44
46
|
import type { KotlinSdkProfile, KotlinToolchain } from './kotlinSdkContract'
|
|
@@ -968,7 +970,7 @@ function appResourceSources(app: KotlinAppProject): Record<string, string> {
|
|
|
968
970
|
.map(([locale, value]) => `${literal(locale)} to ${render(value)}`)
|
|
969
971
|
.join(', ')})`,
|
|
970
972
|
}))
|
|
971
|
-
const
|
|
973
|
+
const tableKinds = [
|
|
972
974
|
{
|
|
973
975
|
type: 'string',
|
|
974
976
|
table: 'peachAppStrings',
|
|
@@ -1007,6 +1009,16 @@ function appResourceSources(app: KotlinAppProject): Record<string, string> {
|
|
|
1007
1009
|
.join(',\n')}\n)`,
|
|
1008
1010
|
})),
|
|
1009
1011
|
},
|
|
1012
|
+
// a layout is its element tree; one only in a qualified directory has none
|
|
1013
|
+
{
|
|
1014
|
+
type: 'layout',
|
|
1015
|
+
table: 'peachAppLayouts',
|
|
1016
|
+
value: 'LayoutNode?',
|
|
1017
|
+
entries: app.layoutIds.layouts.map((name) => {
|
|
1018
|
+
const element = app.layoutIds.elements.get(name)
|
|
1019
|
+
return { name, init: element ? layoutInit(element) : 'null' }
|
|
1020
|
+
}),
|
|
1021
|
+
},
|
|
1010
1022
|
// the day and the night ARGB
|
|
1011
1023
|
{
|
|
1012
1024
|
type: 'color',
|
|
@@ -1017,19 +1029,38 @@ function appResourceSources(app: KotlinAppProject): Record<string, string> {
|
|
|
1017
1029
|
init: `intArrayOf(${argb(color.day)}, ${argb(color.night)})`,
|
|
1018
1030
|
})),
|
|
1019
1031
|
},
|
|
1020
|
-
]
|
|
1032
|
+
]
|
|
1033
|
+
// ids are named in R and in the name table; they hold no Resources value
|
|
1034
|
+
const nameOnly = [{ type: 'id', names: app.layoutIds.ids }]
|
|
1035
|
+
const numbered = <Kind extends { entries: Array<{ name: string }> }>(
|
|
1036
|
+
kind: Kind,
|
|
1037
|
+
index: number,
|
|
1038
|
+
): Omit<Kind, 'entries'> & {
|
|
1039
|
+
entries: Array<Kind['entries'][number] & { id: string }>
|
|
1040
|
+
} => ({
|
|
1021
1041
|
...kind,
|
|
1022
1042
|
entries: kind.entries.map((entry, number) => ({
|
|
1023
1043
|
...entry,
|
|
1024
1044
|
id: id(index + 1, number),
|
|
1025
1045
|
})),
|
|
1026
|
-
})
|
|
1046
|
+
})
|
|
1047
|
+
const kinds = tableKinds.map((kind, index) => numbered(kind, index))
|
|
1048
|
+
const viewClasses = layoutViewClasses(app.layoutIds.elements.values())
|
|
1049
|
+
const rKinds = [
|
|
1050
|
+
...kinds,
|
|
1051
|
+
...nameOnly.map((kind, index) =>
|
|
1052
|
+
numbered(
|
|
1053
|
+
{ type: kind.type, entries: kind.names.map((name) => ({ name })) },
|
|
1054
|
+
kinds.length + index,
|
|
1055
|
+
),
|
|
1056
|
+
),
|
|
1057
|
+
]
|
|
1027
1058
|
return {
|
|
1028
1059
|
'R.kt': [
|
|
1029
1060
|
`package ${app.namespace}`,
|
|
1030
1061
|
'',
|
|
1031
1062
|
'object R {',
|
|
1032
|
-
...
|
|
1063
|
+
...rKinds.flatMap((kind) => [
|
|
1033
1064
|
` object ${kind.type} {`,
|
|
1034
1065
|
...kind.entries.map(
|
|
1035
1066
|
(entry) => ` const val ${field(entry.name)}: Int = ${entry.id}`,
|
|
@@ -1051,6 +1082,10 @@ function appResourceSources(app: KotlinAppProject): Record<string, string> {
|
|
|
1051
1082
|
'androidx.compose.ui.graphics.vector.ImageVector',
|
|
1052
1083
|
'androidx.compose.ui.graphics.vector.addPathNodes',
|
|
1053
1084
|
'androidx.compose.ui.unit.Dp',
|
|
1085
|
+
'android.content.Context',
|
|
1086
|
+
'android.util.AttributeSet',
|
|
1087
|
+
'android.view.LayoutNode',
|
|
1088
|
+
'android.view.View',
|
|
1054
1089
|
].map((name) => `import ${name}`),
|
|
1055
1090
|
'',
|
|
1056
1091
|
...kinds.flatMap((kind) => [
|
|
@@ -1059,16 +1094,45 @@ function appResourceSources(app: KotlinAppProject): Record<string, string> {
|
|
|
1059
1094
|
')',
|
|
1060
1095
|
'',
|
|
1061
1096
|
]),
|
|
1097
|
+
'internal val peachAppViews: Map<String, (Context, AttributeSet?) -> View> = mapOf(',
|
|
1098
|
+
...viewClasses.map(
|
|
1099
|
+
(name) =>
|
|
1100
|
+
` ${literal(name)} to { context, attrs -> ${name}(context, attrs) },`,
|
|
1101
|
+
),
|
|
1102
|
+
')',
|
|
1103
|
+
'',
|
|
1104
|
+
`internal val peachAppNames: Map<Int, String> = mapOf(`,
|
|
1105
|
+
...rKinds.flatMap((kind) =>
|
|
1106
|
+
kind.entries.map(
|
|
1107
|
+
(entry) =>
|
|
1108
|
+
` ${entry.id} to ${literal(`${app.packageName}:${kind.type}/${entry.name}`)},`,
|
|
1109
|
+
),
|
|
1110
|
+
),
|
|
1111
|
+
')',
|
|
1112
|
+
'',
|
|
1062
1113
|
'internal val compiledAppResources = PeachAppResources(',
|
|
1063
1114
|
...kinds.map(
|
|
1064
1115
|
(kind) =>
|
|
1065
1116
|
` ${kind.table.slice('peachApp'.length).toLowerCase()} = ${kind.table},`,
|
|
1066
1117
|
),
|
|
1118
|
+
' views = peachAppViews,',
|
|
1119
|
+
' names = peachAppNames,',
|
|
1067
1120
|
')',
|
|
1068
1121
|
].join('\n'),
|
|
1069
1122
|
}
|
|
1070
1123
|
}
|
|
1071
1124
|
|
|
1125
|
+
// the elements a layout inflates, without the namespace declarations and
|
|
1126
|
+
// tools attributes aapt2 strips
|
|
1127
|
+
function layoutInit(element: XmlElement): string {
|
|
1128
|
+
const attributes = Object.entries(element.attributes)
|
|
1129
|
+
.filter(([key]) => !key.startsWith('xmlns') && !key.startsWith('tools:'))
|
|
1130
|
+
.map(([key, value]) => `${literal(key)} to ${literal(value)}`)
|
|
1131
|
+
return `LayoutNode(${literal(element.name)}, mapOf(${attributes.join(', ')}), listOf(${element.children
|
|
1132
|
+
.map(layoutInit)
|
|
1133
|
+
.join(', ')}))`
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1072
1136
|
// a drawable file's table entry: a vector as the ImageVector.Builder calls
|
|
1073
1137
|
// XmlVectorParser makes, its colors chosen by the configuration's night
|
|
1074
1138
|
// mode; a bitmap as its encoded bytes
|
|
@@ -1171,11 +1235,19 @@ async function compileKotlin(
|
|
|
1171
1235
|
const sdk = await loadKotlinSdk(moduleRoot, toolchain)
|
|
1172
1236
|
const plugin = path.join(sdk.root, 'plugin.jar')
|
|
1173
1237
|
const sdkLibrary = path.join(sdk.root, `${sdkProfile}.klib`)
|
|
1174
|
-
const
|
|
1238
|
+
const javaRead = javaSpecs.length
|
|
1175
1239
|
? await readJavaModuleSpecs(javaSpecs, sdk.root, await ensureToolchain(toolchain))
|
|
1176
1240
|
: null
|
|
1241
|
+
const java =
|
|
1242
|
+
javaRead && javaRead.specs.some((spec) => !spec.application)
|
|
1243
|
+
? { ...javaRead, specs: javaRead.specs.filter((spec) => !spec.application) }
|
|
1244
|
+
: null
|
|
1245
|
+
const applicationJava = javaRead?.specs.filter((spec) => spec.application) ?? []
|
|
1177
1246
|
const generated = {
|
|
1178
1247
|
...sourceGenerated,
|
|
1248
|
+
...Object.fromEntries(
|
|
1249
|
+
applicationJava.map((spec, index) => [`JavaApplication${index}.kt`, spec.source]),
|
|
1250
|
+
),
|
|
1179
1251
|
'PeachBindingsInitialization.kt': [
|
|
1180
1252
|
'@file:OptIn(kotlin.js.ExperimentalJsExport::class)',
|
|
1181
1253
|
'package dev.peach.jni',
|
|
@@ -1209,7 +1281,7 @@ async function compileKotlin(
|
|
|
1209
1281
|
sdk: sdk.sha256,
|
|
1210
1282
|
sdkProfile,
|
|
1211
1283
|
usesSerialization,
|
|
1212
|
-
java:
|
|
1284
|
+
java: javaRead?.sha256,
|
|
1213
1285
|
}),
|
|
1214
1286
|
)
|
|
1215
1287
|
for (const { file, bytes } of inputs)
|
|
@@ -1442,6 +1514,11 @@ async function compileKotlin(
|
|
|
1442
1514
|
: ''
|
|
1443
1515
|
for (const [name, source] of Object.entries(origins))
|
|
1444
1516
|
output = output.replaceAll(path.join(generatedDir, name), source)
|
|
1517
|
+
for (const [index, spec] of applicationJava.entries())
|
|
1518
|
+
output = output.replaceAll(
|
|
1519
|
+
path.join(generatedDir, `JavaApplication${index}.kt`),
|
|
1520
|
+
spec.file,
|
|
1521
|
+
)
|
|
1445
1522
|
for (const { file, target } of compiledSources)
|
|
1446
1523
|
output = output
|
|
1447
1524
|
.replaceAll(target, file)
|