peachsim 0.1.1635 → 0.1.1641
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/README.md +10 -1
- package/cli/app-config.ts +14 -5
- package/cli/app-stubs.ts +96 -22
- package/cli/bridge-flow-runner.ts +2 -2
- package/cli/cloud-client.ts +60 -40
- package/cli/cloud-session.ts +16 -0
- package/cli/commands/assert.ts +17 -4
- package/cli/commands/box.ts +33 -19
- package/cli/commands/doctor.ts +37 -20
- package/cli/commands/flow.ts +1 -1
- package/cli/commands/inspect/actions.ts +3 -2
- package/cli/commands/inspect/core.ts +0 -8
- package/cli/commands/inspect/shared.ts +9 -4
- package/cli/commands/inspect.ts +65 -61
- package/cli/commands/platform.ts +2 -1
- package/cli/commands/preview.ts +1 -1
- package/cli/commands/record.ts +154 -68
- package/cli/commands/swift.ts +18 -4
- package/cli/commands/three-mode.ts +4 -38
- package/cli/commands/upload.ts +55 -49
- package/cli/drivers/playwright-sim-host.ts +65 -42
- package/cli/flow-live-status.ts +0 -2
- package/cli/main.ts +2 -2
- package/cli/outbound-endpoints.ts +7 -5
- package/cli/pause-aware-timeout.ts +4 -0
- package/cli/ws-bridge.ts +19 -16
- package/detox/attempt-events.cjs +99 -6
- package/detox/attempt-events.d.cts +7 -0
- package/detox/expectations.ts +7 -3
- package/detox/index.ts +259 -139
- package/detox/jest-environment.cjs +5 -1
- package/detox/motion-change.cjs +170 -21
- package/detox/motion-change.d.cts +32 -0
- package/detox/navigation-lifecycle.ts +35 -3
- 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 +17 -7
- 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 +5014 -2268
- 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 +1036 -166
- package/dist-lib/detox/jest-environment.cjs +5 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/expo-swift-bundle.cjs +4613 -1963
- package/dist-lib/expo-swift-metadata.cjs +9 -7
- package/dist-lib/expo-swift-metadata.mjs +9 -7
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +58072 -16400
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- 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 +2790 -143
- 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 +1 -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 +2579 -95
- package/dist-lib/native-app-identity-project.cjs +243 -53
- package/dist-lib/native-app-identity-project.mjs +243 -53
- package/dist-lib/native-app-identity.cjs +29 -30
- package/dist-lib/native-app-identity.mjs +29 -30
- package/dist-lib/native-firebase-metadata.cjs +1 -1
- package/dist-lib/native-firebase-metadata.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/react-native-host-modules.cjs +2 -2
- package/dist-lib/react-native-host-modules.mjs +2 -2
- package/dist-lib/scripts/dev-server-scanner.cjs +8 -6
- package/dist-lib/sdk.cjs +4 -3
- package/dist-lib/sdk.mjs +4 -3
- package/dist-lib/skills.cjs +66475 -23097
- package/dist-lib/swift-compile.cjs +452 -260
- package/dist-lib/swift-compile.mjs +451 -252
- package/dist-lib/swift-package.cjs +1 -1
- package/dist-lib/swift-package.mjs +1 -1
- package/dist-lib/swift-submit.cjs +14 -7
- package/dist-lib/swift-submit.mjs +14 -7
- package/dist-lib/swift-toolchain.cjs +316 -41
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite-swift.cjs +8188 -5636
- package/dist-lib/vite.cjs +2857 -12
- package/dist-lib/worklet-executable.cjs +14 -2
- package/dist-lib/worklet-executable.mjs +14 -2
- package/package.json +1 -1
- package/src/backend-origin.ts +21 -6
- package/src/expo-swift-host.ts +5 -2
- package/src/expoKotlinContract.ts +4 -7
- package/src/expoSwiftContract.ts +4 -6
- package/src/host/staged-host-files.ts +9 -0
- package/src/native-app-identity-project.ts +1 -4
- package/src/native-app-identity.ts +1 -4
- package/src/nativeAppIconContract.ts +1 -4
- package/src/output-lock-stdio.ts +36 -0
- package/src/react-native-bridge-modules.ts +106 -78
- package/src/react-native-host-modules.ts +4 -1
- package/src/settings-bundle.ts +1 -4
- package/src/swift-compile.ts +224 -139
- package/src/swift-distribution.lock.json +23 -12
- package/src/swift-distribution.ts +103 -4
- package/src/swift-host.ts +95 -30
- package/src/swift-icu.ts +16 -10
- package/src/swift-objc-compile.ts +547 -0
- package/src/swift-objc-metadata.ts +204 -0
- package/src/swift-objc-sdk.ts +883 -19
- package/src/swift-objc-standin.ts +126 -14
- package/src/swift-package-manifest.ts +42 -1
- package/src/swift-packages.ts +35 -21
- package/src/swift-root-lock.ts +153 -0
- package/src/swift-standin-emit.ts +40 -7
- package/src/swift-standins.ts +404 -138
- package/src/swift-submit.ts +18 -7
- package/src/swift-toolchain.ts +378 -46
- package/src/swiftContract.ts +12 -0
- package/src/worker-system-chunks.ts +11 -12
- package/src/worklet-executable.ts +19 -1
- package/src/xcode-project.ts +280 -33
package/detox/attempt-events.cjs
CHANGED
|
@@ -43,6 +43,15 @@ function proofBoundPath(root, relative) {
|
|
|
43
43
|
return resolved
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
// lifecycle receipts bind every clock and census read to the retained bytes.
|
|
47
|
+
function boundText(root, relative, sha256, label) {
|
|
48
|
+
const bytes = fs.readFileSync(proofBoundPath(root, relative))
|
|
49
|
+
if (proofByteHash(bytes) !== sha256)
|
|
50
|
+
throw new Error(`${label} does not match its recorded hash`)
|
|
51
|
+
return bytes.toString('utf8')
|
|
52
|
+
}
|
|
53
|
+
module.exports.boundText = boundText
|
|
54
|
+
|
|
46
55
|
function authenticateDiscreteFrameAsset(root, declaration, calibrate = false) {
|
|
47
56
|
const cadence = parseDiscreteFrameCadence(declaration)
|
|
48
57
|
const fixture = fs.readFileSync(proofBoundPath(root, cadence.asset.fixturePath))
|
|
@@ -309,6 +318,10 @@ function writeDiscreteFrameReceipt(
|
|
|
309
318
|
}
|
|
310
319
|
|
|
311
320
|
function authenticateNativeCadenceCensus(root, sourceRoot, life, decoded) {
|
|
321
|
+
const {
|
|
322
|
+
authenticateNativeRefreshSamples,
|
|
323
|
+
} = require('../../peach-conformance/e2e/utils/native-frame-receipt.cjs')
|
|
324
|
+
authenticateNativeRefreshSamples(root, sourceRoot, life)
|
|
312
325
|
const native = life.nativeFramebuffer
|
|
313
326
|
if (
|
|
314
327
|
!native ||
|
|
@@ -322,28 +335,71 @@ function authenticateNativeCadenceCensus(root, sourceRoot, life, decoded) {
|
|
|
322
335
|
)
|
|
323
336
|
)
|
|
324
337
|
throw new Error('native cadence has no source-matched framebuffer consumer')
|
|
325
|
-
const frames =
|
|
326
|
-
|
|
338
|
+
const frames = boundText(
|
|
339
|
+
root,
|
|
340
|
+
native.receipt,
|
|
341
|
+
native.receiptSha256,
|
|
342
|
+
'native cadence source receipt',
|
|
343
|
+
)
|
|
327
344
|
.trim()
|
|
328
345
|
.split('\n')
|
|
329
346
|
.map(JSON.parse)
|
|
330
|
-
const media =
|
|
331
|
-
|
|
347
|
+
const media = boundText(
|
|
348
|
+
root,
|
|
349
|
+
native.mediaFrames,
|
|
350
|
+
native.mediaFramesSha256,
|
|
351
|
+
'native cadence sampled surface census',
|
|
352
|
+
)
|
|
332
353
|
.trim()
|
|
333
354
|
.split('\n')
|
|
334
355
|
.map(JSON.parse)
|
|
335
356
|
if (frames.length !== decoded.observations.length || media.length !== frames.length)
|
|
336
|
-
throw new Error('native cadence acquisition and
|
|
357
|
+
throw new Error('native cadence acquisition and sampled surface census differ')
|
|
337
358
|
const {
|
|
338
359
|
decodeNativeFramebuffer,
|
|
339
360
|
requireNativeRawFrame,
|
|
340
361
|
} = require('../../peach-conformance/e2e/utils/native-frame-receipt.cjs')
|
|
341
362
|
const rawRoot = path.dirname(proofBoundPath(root, native.receipt))
|
|
363
|
+
// a callback whose frame a newer one overwrote mid-read keeps no bytes; its
|
|
364
|
+
// superseded receipt fills exactly the gap it leaves in the callback order
|
|
365
|
+
const superseded = new Set(
|
|
366
|
+
boundText(
|
|
367
|
+
root,
|
|
368
|
+
native.superseded,
|
|
369
|
+
native.supersededSha256,
|
|
370
|
+
'native cadence superseded receipt',
|
|
371
|
+
)
|
|
372
|
+
.split('\n')
|
|
373
|
+
.filter(Boolean)
|
|
374
|
+
.map((line) => {
|
|
375
|
+
const row = JSON.parse(line)
|
|
376
|
+
if (
|
|
377
|
+
!Number.isSafeInteger(row.callbackIndex) ||
|
|
378
|
+
row.seedBeforeRead === row.seedAfterRead
|
|
379
|
+
)
|
|
380
|
+
throw new Error('native superseded receipt is not an overwritten read')
|
|
381
|
+
return row.callbackIndex
|
|
382
|
+
}),
|
|
383
|
+
)
|
|
384
|
+
const reads = boundText(
|
|
385
|
+
root,
|
|
386
|
+
native.reads,
|
|
387
|
+
native.readsSha256,
|
|
388
|
+
'native cadence observations',
|
|
389
|
+
)
|
|
390
|
+
.split('\n')
|
|
391
|
+
.filter(Boolean)
|
|
392
|
+
.map(JSON.parse)
|
|
393
|
+
let expectedCallback = 0
|
|
394
|
+
for (const read of reads) {
|
|
395
|
+
while (superseded.delete(expectedCallback)) expectedCallback++
|
|
396
|
+
if (read.callbackIndex !== expectedCallback++)
|
|
397
|
+
throw new Error('native cadence observations have invalid callback order')
|
|
398
|
+
}
|
|
342
399
|
const origin = frames[0].consumerArrival
|
|
343
400
|
for (const [index, frame] of frames.entries()) {
|
|
344
401
|
const clock = frame.consumerArrival
|
|
345
402
|
if (
|
|
346
|
-
frame.callbackIndex !== index ||
|
|
347
403
|
media[index].sourceFrameIndex !== index ||
|
|
348
404
|
!clock ||
|
|
349
405
|
clock.domain !== 'host-mach-absolute-time' ||
|
|
@@ -374,6 +430,9 @@ function authenticateNativeCadenceCensus(root, sourceRoot, life, decoded) {
|
|
|
374
430
|
),
|
|
375
431
|
)
|
|
376
432
|
}
|
|
433
|
+
while (superseded.delete(expectedCallback)) expectedCallback++
|
|
434
|
+
if (superseded.size)
|
|
435
|
+
throw new Error('native superseded receipts fall outside the callback order')
|
|
377
436
|
}
|
|
378
437
|
|
|
379
438
|
function readDiscreteFrameReceipt(root, sourceRoot, reference, expected) {
|
|
@@ -710,10 +769,44 @@ function discreteFrameEvidenceFiles(root, evidence) {
|
|
|
710
769
|
const life = JSON.parse(
|
|
711
770
|
fs.readFileSync(proofBoundPath(root, receipt.lifecycle.path), 'utf8'),
|
|
712
771
|
)
|
|
772
|
+
// the app's ui frame clock and delivered input are replayed from their
|
|
773
|
+
// own receipts, so their bytes travel bound to the hashes the lifecycle
|
|
774
|
+
// recorded
|
|
775
|
+
for (const [label, auxiliary] of [
|
|
776
|
+
['ui frame clock', life.uiFrameClock],
|
|
777
|
+
['delivered input', life.deliveredUIKitInput],
|
|
778
|
+
]) {
|
|
779
|
+
if (!auxiliary) continue
|
|
780
|
+
const bytes = fs.readFileSync(proofBoundPath(root, auxiliary.sourceReceipt))
|
|
781
|
+
if (proofByteHash(bytes) !== auxiliary.sourceReceiptSha256)
|
|
782
|
+
throw new Error(`native ${label} receipt does not match its recorded hash`)
|
|
783
|
+
paths.add(auxiliary.sourceReceipt)
|
|
784
|
+
}
|
|
713
785
|
const native = life.nativeFramebuffer
|
|
714
786
|
if (native) {
|
|
715
787
|
paths.add(native.receipt)
|
|
788
|
+
paths.add(native.superseded)
|
|
716
789
|
paths.add(native.mediaFrames)
|
|
790
|
+
paths.add(native.gradingMarkers)
|
|
791
|
+
paths.add(native.gradingPlan)
|
|
792
|
+
paths.add(native.windowResolution)
|
|
793
|
+
paths.add(native.reads)
|
|
794
|
+
for (const receipt of native.finalReads) {
|
|
795
|
+
const text = boundText(
|
|
796
|
+
root,
|
|
797
|
+
receipt.path,
|
|
798
|
+
receipt.sha256,
|
|
799
|
+
'native sampled end state',
|
|
800
|
+
)
|
|
801
|
+
paths.add(receipt.path)
|
|
802
|
+
for (const row of text.split('\n').filter(Boolean).map(JSON.parse)) {
|
|
803
|
+
const file = proofBoundPath(
|
|
804
|
+
path.dirname(proofBoundPath(root, receipt.path)),
|
|
805
|
+
row.rawPath,
|
|
806
|
+
)
|
|
807
|
+
paths.add(path.relative(root, file).split(path.sep).join('/'))
|
|
808
|
+
}
|
|
809
|
+
}
|
|
717
810
|
const rows = fs
|
|
718
811
|
.readFileSync(proofBoundPath(root, native.receipt), 'utf8')
|
|
719
812
|
.trim()
|
|
@@ -104,3 +104,10 @@ export function writeDiscreteFrameReceipt(
|
|
|
104
104
|
context: DiscreteProofContext,
|
|
105
105
|
trace: DiscreteFrameTrace,
|
|
106
106
|
): DiscreteProofReference
|
|
107
|
+
|
|
108
|
+
export function boundText(
|
|
109
|
+
root: string,
|
|
110
|
+
relative: string,
|
|
111
|
+
sha256: string,
|
|
112
|
+
label: string,
|
|
113
|
+
): string
|
package/detox/expectations.ts
CHANGED
|
@@ -54,8 +54,12 @@ export function isNodeVisible(node: SootSimNodeInfo | null | undefined): boolean
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
// a native host is focused when its editor child holds focus.
|
|
57
|
-
export function focusIsWithin(
|
|
58
|
-
|
|
57
|
+
export function focusIsWithin(
|
|
58
|
+
focused: SootSimFocusedNodeInfo,
|
|
59
|
+
node: SootSimNodeInfo,
|
|
60
|
+
): boolean {
|
|
61
|
+
const nativeNodeId = node.nativeTag ?? node.nodeId
|
|
62
|
+
return focused.nodeId === nativeNodeId || focused.ancestorNodeIds.includes(nativeNodeId)
|
|
59
63
|
}
|
|
60
64
|
|
|
61
65
|
// the engine owns focus for canvas inputs and hosted native editors.
|
|
@@ -64,7 +68,7 @@ export async function isTextInputNodeFocused(
|
|
|
64
68
|
page: Page,
|
|
65
69
|
): Promise<boolean> {
|
|
66
70
|
const focused = await page.evaluate(async () => window.__sootsimTest!.getFocusedNode())
|
|
67
|
-
return focused !== null && focusIsWithin(focused, node
|
|
71
|
+
return focused !== null && focusIsWithin(focused, node)
|
|
68
72
|
}
|
|
69
73
|
|
|
70
74
|
async function isNodeFocused(node: SootSimNodeInfo, page: Page): Promise<boolean> {
|