sootsim 0.1.296 → 0.1.298
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/detox/index.ts +380 -28
- package/detox/motion-change.cjs +109 -0
- package/detox/motion-change.d.cts +35 -0
- package/dist-cli/bin.js +5 -5
- package/dist-cli/chunks/{agent-3F4K6MQK.js → agent-U3HXOT6B.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-5LLVCQRZ.js → agent-wrapper-LJOPJUAN.js} +2 -2
- package/dist-cli/chunks/{app-fonts-LPTY7A5G.js → app-fonts-4EVLV2BX.js} +2 -2
- package/dist-cli/chunks/{assert-R2ZUXEMS.js → assert-NNKBTEO7.js} +2 -2
- package/dist-cli/chunks/{auth-CA62Q6IS.js → auth-SF2WR2K2.js} +2 -2
- package/dist-cli/chunks/{beta-4AXSOQLU.js → beta-SCLWNOHI.js} +2 -2
- package/dist-cli/chunks/{camera-Y4RBIONE.js → camera-TZJ2Z3TZ.js} +2 -2
- package/dist-cli/chunks/{chunk-MDBR4XTV.js → chunk-3R4W2SQB.js} +3 -3
- package/dist-cli/chunks/{chunk-X7B5KJ6N.js → chunk-4H3Y3TGT.js} +1 -1
- package/dist-cli/chunks/{chunk-4MDLYOEI.js → chunk-5VGTEGDT.js} +2 -2
- package/dist-cli/chunks/{chunk-F2MS365Z.js → chunk-6YIZZDG2.js} +2 -2
- package/dist-cli/chunks/{chunk-7V3JNANH.js → chunk-7ZOI5KJZ.js} +2 -2
- package/dist-cli/chunks/{chunk-QIDFGREY.js → chunk-AHMMVYVE.js} +1 -1
- package/dist-cli/chunks/{chunk-ZIBKGZJD.js → chunk-ANFOERLP.js} +1 -1
- package/dist-cli/chunks/{chunk-GG6XOQ5P.js → chunk-APNG6X2R.js} +2 -2
- package/dist-cli/chunks/{chunk-54TQ3ZGI.js → chunk-AT3NTZPP.js} +3 -3
- package/dist-cli/chunks/{chunk-CAAADPRH.js → chunk-BUM4RR4G.js} +2 -2
- package/dist-cli/chunks/{chunk-PEUWZRXA.js → chunk-CAEQ7AOI.js} +3 -3
- package/dist-cli/chunks/{chunk-C462URRQ.js → chunk-CK3MTK2D.js} +2 -2
- package/dist-cli/chunks/{chunk-NEARYPSC.js → chunk-CXSMZLI6.js} +3 -3
- package/dist-cli/chunks/{chunk-HSGS2U7P.js → chunk-EH4B5ZQ4.js} +2 -2
- package/dist-cli/chunks/{chunk-74FOMZP7.js → chunk-EYBWIEDO.js} +2 -2
- package/dist-cli/chunks/{chunk-B2FB6IYX.js → chunk-FTMTIUBK.js} +2 -2
- package/dist-cli/chunks/{chunk-FUPQIX4U.js → chunk-G3NMMKBL.js} +2 -2
- package/dist-cli/chunks/{chunk-MQ6QX46T.js → chunk-GM2TRB5Z.js} +2 -2
- package/dist-cli/chunks/{chunk-CS23DQB2.js → chunk-GR7USTCW.js} +2 -2
- package/dist-cli/chunks/{chunk-AUBP44CY.js → chunk-GXVG5LJG.js} +2 -2
- package/dist-cli/chunks/{chunk-7GQWF7HE.js → chunk-HAJSNFUY.js} +1 -1
- package/dist-cli/chunks/{chunk-222Y7NQA.js → chunk-HG63AS7K.js} +1 -1
- package/dist-cli/chunks/{chunk-LHUY46GE.js → chunk-HGSYUEQP.js} +2 -2
- package/dist-cli/chunks/{chunk-TIOPG6QZ.js → chunk-HOQD6TZN.js} +1 -1
- package/dist-cli/chunks/{chunk-CDCVWGNU.js → chunk-IBMZ7A6M.js} +2 -2
- package/dist-cli/chunks/{chunk-EISE56VD.js → chunk-IRMKZSWK.js} +2 -2
- package/dist-cli/chunks/{chunk-SUJSGGSS.js → chunk-J42Y66IM.js} +2 -2
- package/dist-cli/chunks/{chunk-FROCFR77.js → chunk-JM36NHNU.js} +1 -1
- package/dist-cli/chunks/{chunk-WJVBD2UL.js → chunk-KVYZYYSY.js} +1 -1
- package/dist-cli/chunks/{chunk-3PAZJSIG.js → chunk-MFMFNCBK.js} +2 -2
- package/dist-cli/chunks/{chunk-DUYKBCM7.js → chunk-MHCSRMK4.js} +1 -1
- package/dist-cli/chunks/{chunk-S5Z4HKWX.js → chunk-MTL4DPUK.js} +1 -1
- package/dist-cli/chunks/{chunk-ZPBIHFQW.js → chunk-NRC73NVF.js} +2 -2
- package/dist-cli/chunks/{chunk-6C24WCDK.js → chunk-PLEZAZTJ.js} +2 -2
- package/dist-cli/chunks/{chunk-IR3DUBRF.js → chunk-PYUI2PHI.js} +2 -2
- package/dist-cli/chunks/{chunk-R65XMN4D.js → chunk-QZCVY5BX.js} +1 -1
- package/dist-cli/chunks/{chunk-5FNPAMP4.js → chunk-SQR7NH32.js} +1 -1
- package/dist-cli/chunks/{chunk-XMVVZCIM.js → chunk-TB77ANGH.js} +2 -2
- package/dist-cli/chunks/chunk-THIBWEML.js +4 -0
- package/dist-cli/chunks/{chunk-N3FZRJT7.js → chunk-TTFO75GL.js} +1 -1
- package/dist-cli/chunks/{chunk-4NFGOGB7.js → chunk-U5TY536V.js} +2 -2
- package/dist-cli/chunks/{chunk-7YQXQSG7.js → chunk-UTUBMEFS.js} +1 -1
- package/dist-cli/chunks/{chunk-B2LDO55K.js → chunk-VFI23QUE.js} +1 -1
- package/dist-cli/chunks/{chunk-BVWIR4CD.js → chunk-WDKLXBQR.js} +1 -1
- package/dist-cli/chunks/{chunk-2XUKWIAL.js → chunk-WV6CBQYZ.js} +1 -1
- package/dist-cli/chunks/{chunk-2LQOLMRK.js → chunk-X3STT7I3.js} +1 -1
- package/dist-cli/chunks/{chunk-GG5PWLGC.js → chunk-XITV33JC.js} +2 -2
- package/dist-cli/chunks/{chunk-EJ6BAJKX.js → chunk-ZBETYTSD.js} +1 -1
- package/dist-cli/chunks/{chunk-G2SO5FPN.js → chunk-ZCHO67PX.js} +2 -2
- package/dist-cli/chunks/{cleanup-4RSKYPQ7.js → cleanup-YZPCNPWE.js} +2 -2
- package/dist-cli/chunks/{cli-version-VZFF7GGM.js → cli-version-ECA6G6JQ.js} +2 -2
- package/dist-cli/chunks/{compat-FABLN4UI.js → compat-OM7ODBMO.js} +2 -2
- package/dist-cli/chunks/{config-74J37LKC.js → config-ZIX6LPFG.js} +2 -2
- package/dist-cli/chunks/{control-VBK32Y7F.js → control-BY6UAMKN.js} +2 -2
- package/dist-cli/chunks/daemon-BQ2T53ZA.js +4 -0
- package/dist-cli/chunks/{debug-AOYA2CLR.js → debug-MVPFRIQA.js} +3 -3
- package/dist-cli/chunks/{desktop-G7XWDCTM.js → desktop-ZXH7NRHW.js} +3 -3
- package/dist-cli/chunks/{detox-QXJ3L2ZI.js → detox-4RZ5UER3.js} +2 -2
- package/dist-cli/chunks/{device-NZZ5ZT3Q.js → device-7R4BSFMS.js} +2 -2
- package/dist-cli/chunks/{diagnose-5CAEJ42M.js → diagnose-4JAFIXWD.js} +2 -2
- package/dist-cli/chunks/disk-cleanup-3E7GYLGW.js +4 -0
- package/dist-cli/chunks/drivers-2OW33GOL.js +4 -0
- package/dist-cli/chunks/{film-C25VRUNC.js → film-Q7KZIGBH.js} +3 -3
- package/dist-cli/chunks/flow-QTOSAQ5X.js +4 -0
- package/dist-cli/chunks/help-UE32FDEY.js +4 -0
- package/dist-cli/chunks/{hidden-runtime-alias-NSLIK6XT.js → hidden-runtime-alias-4ZUCLCVJ.js} +2 -2
- package/dist-cli/chunks/{home-paths-OC6JZXIM.js → home-paths-PVZPREN7.js} +2 -2
- package/dist-cli/chunks/inspect-QWR2U3DK.js +4 -0
- package/dist-cli/chunks/install-desktop-R2ZM5ZJH.js +4 -0
- package/dist-cli/chunks/{login-LB4TMM4T.js → login-UMP65DJG.js} +4 -4
- package/dist-cli/chunks/{logout-33IOBD4X.js → logout-F45WBVJV.js} +2 -2
- package/dist-cli/chunks/{maestro-EEVXX536.js → maestro-33RGEXP4.js} +3 -3
- package/dist-cli/chunks/{maestro-generate-ICPWVXGA.js → maestro-generate-5SLZMOMB.js} +3 -3
- package/dist-cli/chunks/{mode-6IXOZDK3.js → mode-LZORZYWP.js} +2 -2
- package/dist-cli/chunks/{optional-demo-registry-KBMC7SNI.js → optional-demo-registry-DIWO7DG5.js} +2 -2
- package/dist-cli/chunks/{perf-CTTJSAIJ.js → perf-VW3UTYCK.js} +2 -2
- package/dist-cli/chunks/{permissions-BFQS4DIY.js → permissions-7JIR6QPO.js} +2 -2
- package/dist-cli/chunks/{record-MJR5ELHE.js → record-A4MRKJ2E.js} +3 -3
- package/dist-cli/chunks/{report-issue-FMJRNDKH.js → report-issue-JUWTB66Z.js} +2 -2
- package/dist-cli/chunks/runtime-7LSOODXL.js +4 -0
- package/dist-cli/chunks/{screenshot-command-MGNASAXR.js → screenshot-command-6LROQJPJ.js} +3 -3
- package/dist-cli/chunks/{screenshots-capture-N6PANAVT.js → screenshots-capture-FMYE24EW.js} +2 -2
- package/dist-cli/chunks/{serve-RS6TIO7U.js → serve-64SRDCU5.js} +2 -2
- package/dist-cli/chunks/{setup-MFYGYR2F.js → setup-2CUXSDQH.js} +2 -2
- package/dist-cli/chunks/{skills-TD35LDKK.js → skills-IILJVUMS.js} +2 -2
- package/dist-cli/chunks/{storage-VCFXDJNO.js → storage-BUQQJAMD.js} +2 -2
- package/dist-cli/chunks/store-3Z2GSFGY.js +4 -0
- package/dist-cli/chunks/telemetry-2UMKQXU7.js +4 -0
- package/dist-cli/chunks/{timeline-UJCZAWJV.js → timeline-62RWUHSF.js} +2 -2
- package/dist-cli/chunks/{upgrade-S24NH4YG.js → upgrade-GHXDTO2A.js} +2 -2
- package/dist-cli/chunks/upload-H6RTYSLO.js +4 -0
- package/dist-cli/chunks/{version-IVPWT2ZQ.js → version-F4CKBMB6.js} +2 -2
- package/dist-cli/chunks/{web-6BMWAWJL.js → web-YM6GIFOU.js} +2 -2
- package/dist-cli/chunks/{what-happened-HRHB6ETL.js → what-happened-UKBSKIGA.js} +2 -2
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.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 +6 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +312 -27
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +1 -1
- 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/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +1 -1
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro.cjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/render-mode.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 +15 -11
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/src/bridge-constants.ts +9 -0
- package/dist-cli/chunks/chunk-P7HBJBHH.js +0 -4
- package/dist-cli/chunks/daemon-VFO7LRR4.js +0 -4
- package/dist-cli/chunks/disk-cleanup-GZSUZJ6Y.js +0 -4
- package/dist-cli/chunks/drivers-OLJCUSPO.js +0 -4
- package/dist-cli/chunks/flow-IW3WUF5D.js +0 -4
- package/dist-cli/chunks/help-GEVJF2DA.js +0 -4
- package/dist-cli/chunks/inspect-KXJNI7CU.js +0 -4
- package/dist-cli/chunks/install-desktop-IYWPRFPB.js +0 -4
- package/dist-cli/chunks/runtime-PV4HH2OB.js +0 -4
- package/dist-cli/chunks/store-VNSTKYBQ.js +0 -4
- package/dist-cli/chunks/telemetry-GPNHSYFF.js +0 -4
- package/dist-cli/chunks/upload-CCKAO2M5.js +0 -4
package/dist-lib/detox/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -7,6 +7,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
7
7
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
8
|
var __getProtoOf = Object.getPrototypeOf;
|
|
9
9
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
11
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
12
|
+
};
|
|
10
13
|
var __export = (target, all) => {
|
|
11
14
|
for (var name in all)
|
|
12
15
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -29,6 +32,83 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
29
32
|
));
|
|
30
33
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
31
34
|
|
|
35
|
+
// detox/motion-change.cjs
|
|
36
|
+
var require_motion_change = __commonJS({
|
|
37
|
+
"detox/motion-change.cjs"(exports2, module2) {
|
|
38
|
+
"use strict";
|
|
39
|
+
var MOTION_CHANGE_DEFINITION2 = Object.freeze({
|
|
40
|
+
channelThreshold: 24,
|
|
41
|
+
minimumChangePercent: 0.1
|
|
42
|
+
});
|
|
43
|
+
function measureMotionChange2(input) {
|
|
44
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
45
|
+
throw new Error("motion change measurement requires an input object");
|
|
46
|
+
}
|
|
47
|
+
if (input.installGlobal === true) {
|
|
48
|
+
globalThis.__sootsimMeasureMotionChange = measureMotionChange2;
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const definition = input.definition;
|
|
52
|
+
if (!definition || typeof definition !== "object" || !Number.isInteger(definition.channelThreshold) || definition.channelThreshold < 0 || definition.channelThreshold > 255 || !Number.isFinite(definition.minimumChangePercent) || definition.minimumChangePercent <= 0 || definition.minimumChangePercent >= 100) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
"motion change definition needs a channel threshold from 0 to 255 and a minimum greater than 0% and less than 100%"
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
const label = typeof input.label === "string" && input.label.length > 0 ? input.label : "motion change";
|
|
58
|
+
let changePixels = input.changePixels;
|
|
59
|
+
let totalPixels = input.totalPixels;
|
|
60
|
+
if (input.baseline !== void 0 || input.candidate !== void 0) {
|
|
61
|
+
const baseline = input.baseline;
|
|
62
|
+
const candidate = input.candidate;
|
|
63
|
+
const width = input.width;
|
|
64
|
+
const height = input.height;
|
|
65
|
+
if (!baseline || !candidate || typeof baseline.length !== "number" || typeof candidate.length !== "number" || !Number.isInteger(width) || !Number.isInteger(height) || width <= 0 || height <= 0) {
|
|
66
|
+
throw new Error(`${label} needs two RGBA pixel arrays and positive dimensions`);
|
|
67
|
+
}
|
|
68
|
+
totalPixels = width * height;
|
|
69
|
+
const expectedBytes = totalPixels * 4;
|
|
70
|
+
if (baseline.length !== expectedBytes || candidate.length !== expectedBytes) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
`${label} pixel data has ${baseline.length}/${candidate.length} bytes; expected ${expectedBytes}`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
changePixels = 0;
|
|
76
|
+
for (let offset = 0; offset < expectedBytes; offset += 4) {
|
|
77
|
+
if (Math.abs(baseline[offset] - candidate[offset]) > definition.channelThreshold || Math.abs(baseline[offset + 1] - candidate[offset + 1]) > definition.channelThreshold || Math.abs(baseline[offset + 2] - candidate[offset + 2]) > definition.channelThreshold || Math.abs(baseline[offset + 3] - candidate[offset + 3]) > definition.channelThreshold) {
|
|
78
|
+
changePixels++;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (!Number.isInteger(totalPixels) || totalPixels <= 0) {
|
|
83
|
+
throw new Error(`${label} has no positive measured region area`);
|
|
84
|
+
}
|
|
85
|
+
if (!Number.isInteger(changePixels) || changePixels < 0 || changePixels > totalPixels) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`${label} changed pixel count ${changePixels} is outside its ${totalPixels}px measured region`
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
const changePercent = changePixels / totalPixels * 100;
|
|
91
|
+
return {
|
|
92
|
+
changePercent,
|
|
93
|
+
changePixels,
|
|
94
|
+
passedMinimum: changePercent >= definition.minimumChangePercent,
|
|
95
|
+
totalPixels
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function measureProofMotionChange(input) {
|
|
99
|
+
return measureMotionChange2({
|
|
100
|
+
...input,
|
|
101
|
+
definition: MOTION_CHANGE_DEFINITION2
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
module2.exports = {
|
|
105
|
+
MOTION_CHANGE_DEFINITION: MOTION_CHANGE_DEFINITION2,
|
|
106
|
+
measureMotionChange: measureMotionChange2,
|
|
107
|
+
measureProofMotionChange
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
32
112
|
// detox/index.ts
|
|
33
113
|
var detox_exports = {};
|
|
34
114
|
__export(detox_exports, {
|
|
@@ -1157,6 +1237,7 @@ var by = {
|
|
|
1157
1237
|
};
|
|
1158
1238
|
|
|
1159
1239
|
// detox/index.ts
|
|
1240
|
+
var import_motion_change = __toESM(require_motion_change(), 1);
|
|
1160
1241
|
var BASE_URL = process.env.SOOTSIM_URL || "http://localhost:5173";
|
|
1161
1242
|
var SCREENSHOT_DIR = process.env.SOOTSIM_SCREENSHOT_DIR || path.join(process.cwd(), "test", "detox-driver", "screenshots");
|
|
1162
1243
|
var DETOX_PLATFORM = process.env.SOOTSIM_PLATFORM === "android" ? "android" : "ios";
|
|
@@ -1582,6 +1663,19 @@ function decodePngDataUrl(dataUrl) {
|
|
|
1582
1663
|
}
|
|
1583
1664
|
return Buffer.from(match[1], "base64");
|
|
1584
1665
|
}
|
|
1666
|
+
function writeFastScreenshotFrames(namePrefix, frames) {
|
|
1667
|
+
ensureScreenshotDir();
|
|
1668
|
+
return frames.map((frame) => {
|
|
1669
|
+
const safeName = `${namePrefix}-${frame.label}`.replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
1670
|
+
const filePath = path.join(SCREENSHOT_DIR, `${safeName}.png`);
|
|
1671
|
+
fs.writeFileSync(filePath, decodePngDataUrl(frame.dataUrl));
|
|
1672
|
+
const { dataUrl: _dataUrl, ...metadata } = frame;
|
|
1673
|
+
return {
|
|
1674
|
+
...metadata,
|
|
1675
|
+
path: filePath
|
|
1676
|
+
};
|
|
1677
|
+
});
|
|
1678
|
+
}
|
|
1585
1679
|
async function captureSootsimPngFast(opts) {
|
|
1586
1680
|
const page = getPage();
|
|
1587
1681
|
const dataUrl = await page.evaluate(
|
|
@@ -2142,8 +2236,221 @@ var device = {
|
|
|
2142
2236
|
async setMenuAnimOverride(progress) {
|
|
2143
2237
|
await dispatchSootsimEventInPage("sootsim:menuAnimOverride", { value: progress });
|
|
2144
2238
|
},
|
|
2145
|
-
|
|
2146
|
-
|
|
2239
|
+
// park every render clock before the interaction, detect the first changed
|
|
2240
|
+
// stepped frame inside the named component, then advance exact 60fps frames
|
|
2241
|
+
// to each requested offset. native extraction also chooses the first frame
|
|
2242
|
+
// at or after an offset, so both sides use the same rounding convention.
|
|
2243
|
+
async takeScreenshotStagesFromVisibleChangeFast(namePrefix, stages, options) {
|
|
2244
|
+
const page = getPage();
|
|
2245
|
+
const token = `motion-${process.pid}-${Date.now()}-${Math.random()}`;
|
|
2246
|
+
await page.evaluate(import_motion_change.measureMotionChange, {
|
|
2247
|
+
definition: import_motion_change.MOTION_CHANGE_DEFINITION,
|
|
2248
|
+
installGlobal: true
|
|
2249
|
+
});
|
|
2250
|
+
const capturePromise = page.evaluate(
|
|
2251
|
+
async (input) => {
|
|
2252
|
+
const captureWindow = window;
|
|
2253
|
+
const live = captureWindow.SootSim?.bridges?.liveComposite;
|
|
2254
|
+
const lockstep = captureWindow.SootSim?.bridges?.lockstepCapture;
|
|
2255
|
+
if (!live || typeof live.captureFresh !== "function") {
|
|
2256
|
+
throw new Error("SootSim live composite bridge is not installed");
|
|
2257
|
+
}
|
|
2258
|
+
if (!lockstep || typeof lockstep.begin !== "function") {
|
|
2259
|
+
throw new Error("SootSim lockstep capture bridge is not installed");
|
|
2260
|
+
}
|
|
2261
|
+
const registry = captureWindow.__sootsimVisibleChangeCaptures ?? (captureWindow.__sootsimVisibleChangeCaptures = {});
|
|
2262
|
+
const state = {
|
|
2263
|
+
cancelled: false,
|
|
2264
|
+
ready: false,
|
|
2265
|
+
triggerCompleted: false
|
|
2266
|
+
};
|
|
2267
|
+
registry[input.token] = state;
|
|
2268
|
+
const measureChange = captureWindow.__sootsimMeasureMotionChange;
|
|
2269
|
+
if (!measureChange) {
|
|
2270
|
+
throw new Error("SootSim motion change definition is not installed");
|
|
2271
|
+
}
|
|
2272
|
+
const captureBitmap = async () => {
|
|
2273
|
+
const { canvas } = await live.captureFresh();
|
|
2274
|
+
if (!canvas) throw new Error("SootSim live composite produced no canvas");
|
|
2275
|
+
return createImageBitmap(canvas);
|
|
2276
|
+
};
|
|
2277
|
+
const boundsFor = (bitmap) => {
|
|
2278
|
+
const scale = input.rootFrame && input.rootFrame.width > 0 ? bitmap.width / input.rootFrame.width : 1;
|
|
2279
|
+
return {
|
|
2280
|
+
height: input.frame ? Math.max(
|
|
2281
|
+
1,
|
|
2282
|
+
Math.min(
|
|
2283
|
+
bitmap.height,
|
|
2284
|
+
Math.ceil((input.frame.y + input.frame.height) * scale)
|
|
2285
|
+
) - Math.max(0, Math.floor(input.frame.y * scale))
|
|
2286
|
+
) : bitmap.height,
|
|
2287
|
+
left: input.frame ? Math.max(0, Math.floor(input.frame.x * scale)) : 0,
|
|
2288
|
+
top: input.frame ? Math.max(0, Math.floor(input.frame.y * scale)) : 0,
|
|
2289
|
+
width: input.frame ? Math.max(
|
|
2290
|
+
1,
|
|
2291
|
+
Math.min(
|
|
2292
|
+
bitmap.width,
|
|
2293
|
+
Math.ceil((input.frame.x + input.frame.width) * scale)
|
|
2294
|
+
) - Math.max(0, Math.floor(input.frame.x * scale))
|
|
2295
|
+
) : bitmap.width
|
|
2296
|
+
};
|
|
2297
|
+
};
|
|
2298
|
+
const regionPixels = (bitmap) => {
|
|
2299
|
+
const bounds = boundsFor(bitmap);
|
|
2300
|
+
const canvas = document.createElement("canvas");
|
|
2301
|
+
canvas.width = bounds.width;
|
|
2302
|
+
canvas.height = bounds.height;
|
|
2303
|
+
const context = canvas.getContext("2d", { willReadFrequently: true });
|
|
2304
|
+
if (!context) throw new Error("SootSim motion detector needs a 2d canvas");
|
|
2305
|
+
context.drawImage(
|
|
2306
|
+
bitmap,
|
|
2307
|
+
bounds.left,
|
|
2308
|
+
bounds.top,
|
|
2309
|
+
bounds.width,
|
|
2310
|
+
bounds.height,
|
|
2311
|
+
0,
|
|
2312
|
+
0,
|
|
2313
|
+
bounds.width,
|
|
2314
|
+
bounds.height
|
|
2315
|
+
);
|
|
2316
|
+
return context.getImageData(0, 0, bounds.width, bounds.height).data;
|
|
2317
|
+
};
|
|
2318
|
+
const encode = (snapshot) => {
|
|
2319
|
+
const canvas = document.createElement("canvas");
|
|
2320
|
+
canvas.width = snapshot.bitmap.width;
|
|
2321
|
+
canvas.height = snapshot.bitmap.height;
|
|
2322
|
+
const context = canvas.getContext("2d");
|
|
2323
|
+
if (!context) throw new Error("SootSim motion capture needs a 2d canvas");
|
|
2324
|
+
context.drawImage(snapshot.bitmap, 0, 0);
|
|
2325
|
+
snapshot.bitmap.close();
|
|
2326
|
+
return {
|
|
2327
|
+
actualMs: snapshot.actualMs,
|
|
2328
|
+
dataUrl: canvas.toDataURL("image/png"),
|
|
2329
|
+
label: snapshot.label,
|
|
2330
|
+
offsetMs: snapshot.offsetMs,
|
|
2331
|
+
frameIndex: snapshot.frameIndex,
|
|
2332
|
+
virtualTimestampMs: snapshot.virtualTimestampMs
|
|
2333
|
+
};
|
|
2334
|
+
};
|
|
2335
|
+
const controller = await lockstep.begin(60);
|
|
2336
|
+
try {
|
|
2337
|
+
const baselineBitmap = await captureBitmap();
|
|
2338
|
+
const baseline = regionPixels(baselineBitmap);
|
|
2339
|
+
baselineBitmap.close();
|
|
2340
|
+
state.ready = true;
|
|
2341
|
+
while (!state.triggerCompleted) {
|
|
2342
|
+
if (state.cancelled) throw new Error("SootSim motion capture was cancelled");
|
|
2343
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
2344
|
+
}
|
|
2345
|
+
let visibleStart = null;
|
|
2346
|
+
let detectedMeasurement = null;
|
|
2347
|
+
const detectionFrameLimit = Math.ceil(input.detectionTimeoutMs * 60 / 1e3);
|
|
2348
|
+
for (let frame = 0; frame < detectionFrameLimit; frame++) {
|
|
2349
|
+
if (state.cancelled) throw new Error("SootSim motion capture was cancelled");
|
|
2350
|
+
const receipt = await controller.stepFrame();
|
|
2351
|
+
const candidateBitmap = await captureBitmap();
|
|
2352
|
+
const bounds = boundsFor(candidateBitmap);
|
|
2353
|
+
const measurement = measureChange({
|
|
2354
|
+
baseline,
|
|
2355
|
+
candidate: regionPixels(candidateBitmap),
|
|
2356
|
+
definition: input.motionChangeDefinition,
|
|
2357
|
+
height: bounds.height,
|
|
2358
|
+
label: "SootSim visible-change detector",
|
|
2359
|
+
width: bounds.width
|
|
2360
|
+
});
|
|
2361
|
+
candidateBitmap.close();
|
|
2362
|
+
if (measurement.passedMinimum) {
|
|
2363
|
+
visibleStart = receipt;
|
|
2364
|
+
detectedMeasurement = measurement;
|
|
2365
|
+
break;
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
if (!visibleStart || !detectedMeasurement) {
|
|
2369
|
+
throw new Error(
|
|
2370
|
+
`SootSim motion had no visible change before ${input.detectionTimeoutMs}ms`
|
|
2371
|
+
);
|
|
2372
|
+
}
|
|
2373
|
+
const snapshots = [];
|
|
2374
|
+
for (const stage of input.stages) {
|
|
2375
|
+
if (state.cancelled) throw new Error("SootSim motion capture was cancelled");
|
|
2376
|
+
const receipt = await controller.stepToOffset(visibleStart, stage.offsetMs);
|
|
2377
|
+
snapshots.push({
|
|
2378
|
+
actualMs: receipt.virtualTimestampMs - visibleStart.virtualTimestampMs,
|
|
2379
|
+
bitmap: await captureBitmap(),
|
|
2380
|
+
frameIndex: receipt.frameIndex,
|
|
2381
|
+
label: stage.label,
|
|
2382
|
+
offsetMs: stage.offsetMs,
|
|
2383
|
+
virtualTimestampMs: receipt.virtualTimestampMs
|
|
2384
|
+
});
|
|
2385
|
+
}
|
|
2386
|
+
return {
|
|
2387
|
+
frames: snapshots.map(encode),
|
|
2388
|
+
visibleChangeDetection: {
|
|
2389
|
+
actualMs: visibleStart.frameIndex * 1e3 / 60,
|
|
2390
|
+
changedPixelPercent: detectedMeasurement.changePercent,
|
|
2391
|
+
changedPixels: detectedMeasurement.changePixels,
|
|
2392
|
+
channelThreshold: input.motionChangeDefinition.channelThreshold,
|
|
2393
|
+
minimumChangePercent: input.motionChangeDefinition.minimumChangePercent,
|
|
2394
|
+
totalPixels: detectedMeasurement.totalPixels,
|
|
2395
|
+
frameIndex: visibleStart.frameIndex,
|
|
2396
|
+
virtualTimestampMs: visibleStart.virtualTimestampMs
|
|
2397
|
+
}
|
|
2398
|
+
};
|
|
2399
|
+
} finally {
|
|
2400
|
+
controller.end();
|
|
2401
|
+
delete registry[input.token];
|
|
2402
|
+
}
|
|
2403
|
+
},
|
|
2404
|
+
{
|
|
2405
|
+
detectionTimeoutMs: options.detectionTimeoutMs ?? 3e3,
|
|
2406
|
+
frame: options.frame ?? null,
|
|
2407
|
+
motionChangeDefinition: import_motion_change.MOTION_CHANGE_DEFINITION,
|
|
2408
|
+
rootFrame: options.rootFrame ?? null,
|
|
2409
|
+
stages,
|
|
2410
|
+
token
|
|
2411
|
+
}
|
|
2412
|
+
);
|
|
2413
|
+
await page.waitForFunction(
|
|
2414
|
+
(captureToken) => {
|
|
2415
|
+
const registry = window.__sootsimVisibleChangeCaptures;
|
|
2416
|
+
return registry?.[captureToken]?.ready === true;
|
|
2417
|
+
},
|
|
2418
|
+
token,
|
|
2419
|
+
{ timeout: 5e3 }
|
|
2420
|
+
);
|
|
2421
|
+
const triggerStartMs = Date.now();
|
|
2422
|
+
let triggerCompletedMs = 0;
|
|
2423
|
+
try {
|
|
2424
|
+
await Promise.resolve(options.trigger());
|
|
2425
|
+
triggerCompletedMs = Date.now();
|
|
2426
|
+
await page.evaluate((captureToken) => {
|
|
2427
|
+
const registry = window.__sootsimVisibleChangeCaptures;
|
|
2428
|
+
const capture2 = registry?.[captureToken];
|
|
2429
|
+
if (!capture2) throw new Error("SootSim motion capture disarmed before trigger");
|
|
2430
|
+
capture2.triggerCompleted = true;
|
|
2431
|
+
}, token);
|
|
2432
|
+
const capture = await capturePromise;
|
|
2433
|
+
return {
|
|
2434
|
+
frames: writeFastScreenshotFrames(namePrefix, capture.frames),
|
|
2435
|
+
triggerCompletedMs,
|
|
2436
|
+
triggerStartMs,
|
|
2437
|
+
visibleChangeDetection: {
|
|
2438
|
+
...capture.visibleChangeDetection,
|
|
2439
|
+
frame: options.frame ?? null,
|
|
2440
|
+
rootFrame: options.rootFrame ?? null
|
|
2441
|
+
}
|
|
2442
|
+
};
|
|
2443
|
+
} catch (error) {
|
|
2444
|
+
await page.evaluate((captureToken) => {
|
|
2445
|
+
const registry = window.__sootsimVisibleChangeCaptures;
|
|
2446
|
+
const capture = registry?.[captureToken];
|
|
2447
|
+
if (capture) capture.cancelled = true;
|
|
2448
|
+
}, token).catch(() => {
|
|
2449
|
+
});
|
|
2450
|
+
await capturePromise.catch(() => {
|
|
2451
|
+
});
|
|
2452
|
+
throw error;
|
|
2453
|
+
}
|
|
2147
2454
|
},
|
|
2148
2455
|
// FAST multi-stage capture for sub-second animation diffs. each stage
|
|
2149
2456
|
// schedules a setTimeout at its requested offsetMs and at that moment
|
|
@@ -2236,18 +2543,7 @@ var device = {
|
|
|
2236
2543
|
},
|
|
2237
2544
|
{ stages, skipWarmup: options?.skipWarmup === true }
|
|
2238
2545
|
);
|
|
2239
|
-
|
|
2240
|
-
return frames.map((f) => {
|
|
2241
|
-
const safeName = `${namePrefix}-${f.label}`.replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
2242
|
-
const filePath = path.join(SCREENSHOT_DIR, `${safeName}.png`);
|
|
2243
|
-
fs.writeFileSync(filePath, decodePngDataUrl(f.dataUrl));
|
|
2244
|
-
return {
|
|
2245
|
-
label: f.label,
|
|
2246
|
-
offsetMs: f.offsetMs,
|
|
2247
|
-
actualMs: f.actualMs,
|
|
2248
|
-
path: filePath
|
|
2249
|
-
};
|
|
2250
|
-
});
|
|
2546
|
+
return writeFastScreenshotFrames(namePrefix, frames);
|
|
2251
2547
|
},
|
|
2252
2548
|
// batched multi-stage capture for animation diffs. all N captures happen
|
|
2253
2549
|
// inside one page.evaluate round trip so browser-side timing controls the
|
|
@@ -2277,18 +2573,7 @@ var device = {
|
|
|
2277
2573
|
},
|
|
2278
2574
|
{ stages }
|
|
2279
2575
|
);
|
|
2280
|
-
|
|
2281
|
-
return frames.map((f) => {
|
|
2282
|
-
const safeName = `${namePrefix}-${f.label}`.replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
2283
|
-
const filePath = path.join(SCREENSHOT_DIR, `${safeName}.png`);
|
|
2284
|
-
fs.writeFileSync(filePath, decodePngDataUrl(f.dataUrl));
|
|
2285
|
-
return {
|
|
2286
|
-
label: f.label,
|
|
2287
|
-
offsetMs: f.offsetMs,
|
|
2288
|
-
actualMs: f.actualMs,
|
|
2289
|
-
path: filePath
|
|
2290
|
-
};
|
|
2291
|
-
});
|
|
2576
|
+
return writeFastScreenshotFrames(namePrefix, frames);
|
|
2292
2577
|
},
|
|
2293
2578
|
async shake() {
|
|
2294
2579
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/home-paths.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
|
|
3
3
|
// src/host/fetch-proxy-overrides.ts
|
|
4
4
|
var FETCH_PROXY_BROWSER_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/menu.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/menu.mjs
CHANGED
package/dist-lib/metro.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/dist-lib/profiles.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/dist-lib/render-mode.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/dist-lib/sdk.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
package/dist-lib/sdk.mjs
CHANGED
package/dist-lib/skills.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -1518,10 +1518,10 @@ var init_registry = __esm({
|
|
|
1518
1518
|
versions: [
|
|
1519
1519
|
{
|
|
1520
1520
|
range: ">=1.0.0",
|
|
1521
|
-
coverage: 0.
|
|
1522
|
-
note: "
|
|
1523
|
-
working: "
|
|
1524
|
-
missing: "
|
|
1521
|
+
coverage: 0.85,
|
|
1522
|
+
note: "native-seam only: the published Clipboard object, NativeEventEmitter wiring, and useClipboard hook run from the bundle. RNCClipboard routes text through navigator.clipboard and images through ClipboardItem where the browser exposes it.",
|
|
1523
|
+
working: "published Clipboard object and two-item useClipboard hook, getString/setString/hasString, getImage/getImagePNG/getImageJPG/setImage/hasImage, hasURL/hasWebURL/hasNumber, load-safe listener methods",
|
|
1524
|
+
missing: "external-app clipboard-change events because browsers expose no matching event; setStrings joins values and getStrings returns one browser text item rather than preserving multiple pasteboard strings; Firefox image read because Clipboard.read is unavailable"
|
|
1525
1525
|
}
|
|
1526
1526
|
]
|
|
1527
1527
|
},
|
|
@@ -3881,9 +3881,9 @@ var init_registry = __esm({
|
|
|
3881
3881
|
{
|
|
3882
3882
|
range: ">=0.30.0",
|
|
3883
3883
|
coverage: 0.3,
|
|
3884
|
-
note: "
|
|
3885
|
-
working: "
|
|
3886
|
-
missing: "
|
|
3884
|
+
note: "native-seam only: the published Nitro Modules entrypoint installs a load-safe framework proxy, but no native JSI bindings run",
|
|
3885
|
+
working: "published entrypoint and type exports, NitroModules metadata, createHybridObject chainable proxy, hasHybridObject/getAllHybridObjectNames unavailable state, isRuntimeAlive false, callback wrapper, getHybridObjectConstructor",
|
|
3886
|
+
missing: "the native JSI framework implementation; package-specific HybridObjects work only where a separate compat seam registers them, and native memory accounting, ArrayBuffer ownership, cross-runtime boxed HybridObjects, and Nitro Views remain absent"
|
|
3887
3887
|
}
|
|
3888
3888
|
]
|
|
3889
3889
|
},
|
|
@@ -4174,10 +4174,10 @@ var init_registry = __esm({
|
|
|
4174
4174
|
versions: [
|
|
4175
4175
|
{
|
|
4176
4176
|
range: ">=2.0.0",
|
|
4177
|
-
coverage: 0.
|
|
4177
|
+
coverage: 0.85,
|
|
4178
4178
|
note: "pure JS WHATWG URL/URLSearchParams polyfill; NativeModules.BlobModule access is guarded",
|
|
4179
4179
|
working: "URL, URLSearchParams, setupURLPolyfill, auto.js web guard, canParse, global URL/URLSearchParams installation",
|
|
4180
|
-
missing: "React Native BlobModule-specific createObjectURL
|
|
4180
|
+
missing: "URLSearchParams.sort does not reorder keys in the published 3.0.0 dependency; React Native BlobModule-specific createObjectURL is absent when BlobModule is unavailable, so browser Blob URLs should use the native URL implementation"
|
|
4181
4181
|
}
|
|
4182
4182
|
]
|
|
4183
4183
|
},
|
|
@@ -4555,7 +4555,7 @@ var init_registry = __esm({
|
|
|
4555
4555
|
range: ">=3.0.0",
|
|
4556
4556
|
coverage: 0.95,
|
|
4557
4557
|
note: "pure JS React error boundary with RN fallback UI",
|
|
4558
|
-
working: "ErrorBoundary component,
|
|
4558
|
+
working: "ErrorBoundary component, bundled fallback UI, custom FallbackComponent, onError callback, resetError recovery",
|
|
4559
4559
|
missing: "fallback rendering fidelity follows core RN View/Text/Button primitives"
|
|
4560
4560
|
}
|
|
4561
4561
|
]
|
|
@@ -10713,6 +10713,7 @@ __export(bridge_constants_exports, {
|
|
|
10713
10713
|
DEFAULT_SOOTSIM_BRIDGE_URL: () => DEFAULT_SOOTSIM_BRIDGE_URL,
|
|
10714
10714
|
SOOTSIM_BRIDGE_SIM_CLOSE_CODE: () => SOOTSIM_BRIDGE_SIM_CLOSE_CODE,
|
|
10715
10715
|
SOOTSIM_BRIDGE_SIM_CLOSE_REASON: () => SOOTSIM_BRIDGE_SIM_CLOSE_REASON,
|
|
10716
|
+
isSootsimBridgeHealth: () => isSootsimBridgeHealth,
|
|
10716
10717
|
resolveSootsimBridgePort: () => resolveSootsimBridgePort,
|
|
10717
10718
|
resolveSootsimBridgePortForHttpPort: () => resolveSootsimBridgePortForHttpPort,
|
|
10718
10719
|
resolveSootsimBridgePortForRuntimeLocation: () => resolveSootsimBridgePortForRuntimeLocation,
|
|
@@ -10809,6 +10810,9 @@ function resolveSootsimBridgeWebSocketUrl(input) {
|
|
|
10809
10810
|
href: input.href
|
|
10810
10811
|
});
|
|
10811
10812
|
}
|
|
10813
|
+
function isSootsimBridgeHealth(value, expectedPort) {
|
|
10814
|
+
return typeof value === "object" && value !== null && Reflect.get(value, "ok") === true && Reflect.get(value, "bridgePort") === expectedPort;
|
|
10815
|
+
}
|
|
10812
10816
|
var DEFAULT_SOOTSIM_BRIDGE_PORT, DEFAULT_SOOTSIM_BRIDGE_URL, CONTRAST_DEV_HTTP_BASE_PORT, SOOTSIM_SITE_DEV_HTTP_BASE_PORT, SOOTSIM_SHELL_DEV_HTTP_BASE_PORT, LOCAL_DEV_HTTP_BASE_PORTS, MAX_LOCAL_DEV_PORT_OFFSET, SOOTSIM_BRIDGE_SIM_CLOSE_CODE, SOOTSIM_BRIDGE_SIM_CLOSE_REASON;
|
|
10813
10817
|
var init_bridge_constants = __esm({
|
|
10814
10818
|
"src/bridge-constants.ts"() {
|
package/dist-lib/vite.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sootsim v0.1.
|
|
1
|
+
/*! sootsim v0.1.298 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/package.json
CHANGED
package/src/bridge-constants.ts
CHANGED
|
@@ -140,6 +140,15 @@ export function resolveSootsimBridgeWebSocketUrl(input: {
|
|
|
140
140
|
})
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
export function isSootsimBridgeHealth(value: unknown, expectedPort: number): boolean {
|
|
144
|
+
return (
|
|
145
|
+
typeof value === 'object' &&
|
|
146
|
+
value !== null &&
|
|
147
|
+
Reflect.get(value, 'ok') === true &&
|
|
148
|
+
Reflect.get(value, 'bridgePort') === expectedPort
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
|
|
143
152
|
// private websocket close code used when the daemon intentionally closes a
|
|
144
153
|
// sim. browser clients treat it as terminal and skip their normal reconnect
|
|
145
154
|
// loop; playwright-owned sims use it to close their hosting context.
|