@ceraph/react-native-mcp 0.3.3 → 0.4.5

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.
Files changed (132) hide show
  1. package/README.md +335 -68
  2. package/dist/babel-plugin/index.cjs +1 -0
  3. package/dist/babel-plugin/index.js +1 -0
  4. package/dist/cli.d.ts +3 -1
  5. package/dist/cli.js +1 -47
  6. package/dist/index.d.ts +106 -1
  7. package/dist/index.js +2 -1651
  8. package/dist/shim/async-storage-ops.d.ts +26 -0
  9. package/dist/shim/async-storage-ops.js +1 -0
  10. package/dist/shim/boot.d.ts +9 -0
  11. package/dist/shim/boot.js +1 -141
  12. package/dist/shim/camera.js +1 -62
  13. package/dist/shim/command-poll.d.ts +18 -0
  14. package/dist/shim/command-poll.js +1 -0
  15. package/dist/shim/config.js +1 -56
  16. package/dist/shim/console-capture.d.ts +16 -0
  17. package/dist/shim/console-capture.js +1 -0
  18. package/dist/shim/deep-link.js +1 -25
  19. package/dist/shim/dev-guard.js +1 -3
  20. package/dist/shim/dev-host.d.ts +1 -0
  21. package/dist/shim/dev-host.js +1 -0
  22. package/dist/shim/error-handler.js +1 -66
  23. package/dist/shim/fetch-interceptor.js +1 -93
  24. package/dist/shim/index.d.ts +3 -0
  25. package/dist/shim/index.js +1 -6
  26. package/dist/shim/keep-awake.js +1 -118
  27. package/dist/shim/network-ownership.d.ts +4 -0
  28. package/dist/shim/network-ownership.js +1 -0
  29. package/dist/shim/optimistic-observer.d.ts +29 -0
  30. package/dist/shim/optimistic-observer.js +1 -0
  31. package/dist/shim/reload.js +1 -76
  32. package/dist/shim/reset.d.ts +30 -0
  33. package/dist/shim/reset.js +1 -0
  34. package/dist/shim/signal-capture.d.ts +8 -0
  35. package/dist/shim/signal-capture.js +1 -15
  36. package/dist/shim/signal-transport.d.ts +14 -1
  37. package/dist/shim/signal-transport.js +1 -43
  38. package/dist/shim/xhr-interceptor.d.ts +39 -0
  39. package/dist/shim/xhr-interceptor.js +1 -0
  40. package/package.json +40 -11
  41. package/dist/app-lifecycle.d.ts +0 -50
  42. package/dist/app-lifecycle.js +0 -487
  43. package/dist/camera-image-writer.d.ts +0 -43
  44. package/dist/camera-image-writer.js +0 -280
  45. package/dist/camera-registry-sync.d.ts +0 -18
  46. package/dist/camera-registry-sync.js +0 -117
  47. package/dist/device-autonomy.d.ts +0 -30
  48. package/dist/device-autonomy.js +0 -117
  49. package/dist/error-parser.d.ts +0 -51
  50. package/dist/error-parser.js +0 -275
  51. package/dist/expo-manager.d.ts +0 -62
  52. package/dist/expo-manager.js +0 -447
  53. package/dist/init/ast-camera.d.ts +0 -29
  54. package/dist/init/ast-camera.js +0 -267
  55. package/dist/init/ast-layout.d.ts +0 -15
  56. package/dist/init/ast-layout.js +0 -167
  57. package/dist/init/claude-hook-constants.d.ts +0 -9
  58. package/dist/init/claude-hook-constants.js +0 -91
  59. package/dist/init/lan-ip.d.ts +0 -11
  60. package/dist/init/lan-ip.js +0 -51
  61. package/dist/init/monorepo.d.ts +0 -13
  62. package/dist/init/monorepo.js +0 -185
  63. package/dist/init/oauth.d.ts +0 -52
  64. package/dist/init/oauth.js +0 -220
  65. package/dist/init/package-manager.d.ts +0 -11
  66. package/dist/init/package-manager.js +0 -60
  67. package/dist/init/prompt.d.ts +0 -12
  68. package/dist/init/prompt.js +0 -68
  69. package/dist/init/shell-profile.d.ts +0 -22
  70. package/dist/init/shell-profile.js +0 -85
  71. package/dist/init/steps.d.ts +0 -135
  72. package/dist/init/steps.js +0 -399
  73. package/dist/init/url-scheme.d.ts +0 -42
  74. package/dist/init/url-scheme.js +0 -187
  75. package/dist/init/walkthrough.d.ts +0 -76
  76. package/dist/init/walkthrough.js +0 -340
  77. package/dist/init.d.ts +0 -8
  78. package/dist/init.js +0 -395
  79. package/dist/iproxy-manager.d.ts +0 -32
  80. package/dist/iproxy-manager.js +0 -216
  81. package/dist/mac-caffeinate.d.ts +0 -10
  82. package/dist/mac-caffeinate.js +0 -56
  83. package/dist/permission-interceptor.d.ts +0 -29
  84. package/dist/permission-interceptor.js +0 -185
  85. package/dist/prebuild-detector.d.ts +0 -19
  86. package/dist/prebuild-detector.js +0 -174
  87. package/dist/preflight.d.ts +0 -34
  88. package/dist/preflight.js +0 -847
  89. package/dist/screen.d.ts +0 -184
  90. package/dist/screen.js +0 -931
  91. package/dist/signal-listener.d.ts +0 -27
  92. package/dist/signal-listener.js +0 -135
  93. package/dist/simulator-boot.d.ts +0 -52
  94. package/dist/simulator-boot.js +0 -227
  95. package/dist/target.d.ts +0 -48
  96. package/dist/target.js +0 -267
  97. package/dist/uninstall/cli-runner.d.ts +0 -32
  98. package/dist/uninstall/cli-runner.js +0 -223
  99. package/dist/uninstall/footprint.d.ts +0 -40
  100. package/dist/uninstall/footprint.js +0 -288
  101. package/dist/uninstall/mcp-tools.d.ts +0 -14
  102. package/dist/uninstall/mcp-tools.js +0 -175
  103. package/dist/uninstall/revert-auth.d.ts +0 -22
  104. package/dist/uninstall/revert-auth.js +0 -31
  105. package/dist/uninstall/revert-boot.d.ts +0 -24
  106. package/dist/uninstall/revert-boot.js +0 -242
  107. package/dist/uninstall/revert-camera.d.ts +0 -12
  108. package/dist/uninstall/revert-camera.js +0 -199
  109. package/dist/uninstall/revert-ceraph-dir.d.ts +0 -27
  110. package/dist/uninstall/revert-ceraph-dir.js +0 -38
  111. package/dist/uninstall/revert-claude-hooks.d.ts +0 -19
  112. package/dist/uninstall/revert-claude-hooks.js +0 -191
  113. package/dist/uninstall/revert-gitignore.d.ts +0 -17
  114. package/dist/uninstall/revert-gitignore.js +0 -43
  115. package/dist/uninstall/revert-mcp-clients.d.ts +0 -57
  116. package/dist/uninstall/revert-mcp-clients.js +0 -194
  117. package/dist/uninstall/revert-package.d.ts +0 -34
  118. package/dist/uninstall/revert-package.js +0 -98
  119. package/dist/uninstall/revert-scheme.d.ts +0 -36
  120. package/dist/uninstall/revert-scheme.js +0 -139
  121. package/dist/uninstall/revert-signal-host-env.d.ts +0 -31
  122. package/dist/uninstall/revert-signal-host-env.js +0 -61
  123. package/dist/uninstall/walkthrough.d.ts +0 -80
  124. package/dist/uninstall/walkthrough.js +0 -1244
  125. package/dist/utils/atomic-write.d.ts +0 -1
  126. package/dist/utils/atomic-write.js +0 -30
  127. package/dist/wait-for-device.d.ts +0 -68
  128. package/dist/wait-for-device.js +0 -368
  129. package/dist/wda-manager.d.ts +0 -38
  130. package/dist/wda-manager.js +0 -186
  131. package/dist/wda-simulator.d.ts +0 -28
  132. package/dist/wda-simulator.js +0 -257
@@ -0,0 +1,26 @@
1
+ import { type TransportOptions } from "./signal-transport.js";
2
+ interface AsyncStorageLike {
3
+ getItem: (key: string) => Promise<string | null>;
4
+ multiGet: (keys: string[]) => Promise<Array<[string, string | null]>>;
5
+ multiRemove: (keys: string[]) => Promise<void>;
6
+ }
7
+ interface DeleteKeysDeps {
8
+ asyncStorage?: AsyncStorageLike | null;
9
+ }
10
+ interface InstallBootObserverDeps extends DeleteKeysDeps {
11
+ transport?: TransportOptions;
12
+ }
13
+ export interface DeleteKeysResult {
14
+ cleared: boolean;
15
+ requested: number;
16
+ reason?: string;
17
+ }
18
+ export declare function exposeDeleteKeysHook(deps?: DeleteKeysDeps): void;
19
+ export declare function deleteKeys(keys: string[], deps?: DeleteKeysDeps): Promise<DeleteKeysResult>;
20
+ export interface InstallBootObserverResult {
21
+ installed: boolean;
22
+ reason?: string;
23
+ }
24
+ export declare function installAsyncStorageBootObserver(deps?: InstallBootObserverDeps): InstallBootObserverResult;
25
+ export declare function _resetForTesting(deps?: DeleteKeysDeps): void;
26
+ export {};
@@ -0,0 +1 @@
1
+ import{isDevRuntime}from'./dev-guard.js';import{postSignal}from'./signal-transport.js';export function exposeDeleteKeysHook(a={}){if(!isDevRuntime())return;const b=globalThis;b['__ceraphDeleteKeys']=c=>deleteKeys(c,a);}export async function deleteKeys(a,b={}){if(!isDevRuntime())return{'cleared':![],'requested':a['length'],'reason':'production'};if(!Array['isArray'](a)||a['length']===0x0)return{'cleared':![],'requested':0x0,'reason':'no-keys'};const c=a['filter'](e=>typeof e==='string'&&e['length']>0x0);if(c['length']===0x0)return{'cleared':![],'requested':0x0,'reason':'no-keys'};const d=b['asyncStorage']===null?null:b['asyncStorage']??loadAsyncStorage();if(!d)return{'cleared':![],'requested':c['length'],'reason':'AsyncStorage\x20not\x20installed'};try{return await d['multiRemove'](c),{'cleared':!![],'requested':c['length']};}catch(e){return{'cleared':![],'requested':c['length'],'reason':e?.['message']??'AsyncStorage.multiRemove\x20failed'};}}export function installAsyncStorageBootObserver(a={}){if(!isDevRuntime())return{'installed':![],'reason':'production'};const b=a['asyncStorage']===null?null:a['asyncStorage']??loadAsyncStorage();if(!b)return{'installed':![],'reason':'AsyncStorage\x20not\x20installed'};const c=b,d=c['__ceraphOriginalGetItem']??c['getItem']['bind'](b),e=c['__ceraphOriginalMultiGet']??c['multiGet']['bind'](b),f=async h=>{const i=await d(h);return void emitRead(h,i,a['transport']),i;},g=async h=>{const i=await e(h);for(const [j,l]of i){void emitRead(j,l,a['transport']);}return i;};return c['getItem']=f,c['multiGet']=g,c['__ceraphOriginalGetItem']=d,c['__ceraphOriginalMultiGet']=e,{'installed':!![]};}async function emitRead(a,b,c){let d,e;if(b===null)d='null';else{if(b['length']===0x0)d='empty';else{d='len='+b['length'];try{e=await hashShortPrefix(b);}catch{}}}await postSignal({'kind':'async-storage-read','message':d,'timestampMs':Date['now'](),'key':a,...e?{'valueHash':e}:{}},c)['catch'](()=>undefined);}async function hashShortPrefix(a){const c=globalThis['crypto']?.['subtle'];if(c&&typeof TextEncoder!=='undefined'){const f=new TextEncoder()['encode'](a),g=await c['digest']('SHA-256',f),j=new Uint8Array(g);let k='';for(let l=0x0;l<0x6;l++){const m=j[l]??0x0;k+=m['toString'](0x10)['padStart'](0x2,'0');}return k;}let d=0xdeadbeef^a['length'];for(let n=0x0;n<a['length'];n++){d=Math['imul'](d^a['charCodeAt'](n),0x9e3779b1);}const e=d>>>0x0;return e['toString'](0x10)['padStart'](0xc,'0')['slice'](0x0,0xc);}function loadAsyncStorage(){try{const a=require('@react-native-async-storage/async-storage');if(!a)return undefined;const b=a['default']??a;if(b&&typeof b['getItem']==='function'&&typeof b['multiGet']==='function'&&typeof b['multiRemove']==='function')return b;return undefined;}catch{return undefined;}}export function _resetForTesting(a={}){const b=globalThis;b['__ceraphDeleteKeys']=undefined;const c=a['asyncStorage']===null?null:a['asyncStorage']??loadAsyncStorage();if(!c)return;const d=c;d['__ceraphOriginalGetItem']&&(d['getItem']=d['__ceraphOriginalGetItem'],d['__ceraphOriginalGetItem']=undefined),d['__ceraphOriginalMultiGet']&&(d['multiGet']=d['__ceraphOriginalMultiGet'],d['__ceraphOriginalMultiGet']=undefined);}
@@ -1,3 +1,4 @@
1
+ import { type InstallBootObserverResult } from "./async-storage-ops.js";
1
2
  interface LinkingLike {
2
3
  addEventListener: (type: "url", handler: (event: {
3
4
  url: string;
@@ -24,6 +25,11 @@ interface InstallCeraphDeps {
24
25
  appState?: AppStateLike | null;
25
26
  keepAwake?: KeepAwakeLike | null;
26
27
  applyCameraImageRegistry?: ApplyRegistryFn | null;
28
+ installAsyncStorageObserver?: (() => InstallBootObserverResult) | null;
29
+ readTestidConfig?: (() => {
30
+ pluginVersion?: string;
31
+ babelConfigHash?: string;
32
+ } | null) | null;
27
33
  }
28
34
  export interface InstallCeraphResult {
29
35
  cameraRegistryApplied: boolean;
@@ -32,9 +38,12 @@ export interface InstallCeraphResult {
32
38
  errorHandler: boolean;
33
39
  fetchInterceptor: boolean;
34
40
  reloadListener: boolean;
41
+ resetListener: boolean;
35
42
  } | null;
36
43
  keepAwakeActivated: boolean;
37
44
  appStateListenerInstalled: boolean;
45
+ asyncStorageObserverInstalled: boolean;
46
+ testidSentinelPosted: boolean;
38
47
  }
39
48
  export declare function installCeraph(deps?: InstallCeraphDeps): InstallCeraphResult;
40
49
  export declare function _resetForTesting(): void;
package/dist/shim/boot.js CHANGED
@@ -1,141 +1 @@
1
- import { handleCeraphDeepLink } from "./deep-link.js";
2
- import { isDevRuntime } from "./dev-guard.js";
3
- import { disableKeepAwake, enableKeepAwake } from "./keep-awake.js";
4
- import { installSignalCapture } from "./signal-capture.js";
5
- let currentDeepLinkSub;
6
- let currentAppStateSub;
7
- export function installCeraph(deps = {}) {
8
- if (!isDevRuntime()) {
9
- return {
10
- cameraRegistryApplied: false,
11
- deepLinkListenerInstalled: false,
12
- signalCapture: null,
13
- keepAwakeActivated: false,
14
- appStateListenerInstalled: false,
15
- };
16
- }
17
- let cameraRegistryApplied = false;
18
- const applyRegistry = deps.applyCameraImageRegistry === undefined
19
- ? loadGeneratedRegistry()
20
- : deps.applyCameraImageRegistry;
21
- if (applyRegistry) {
22
- try {
23
- applyRegistry();
24
- cameraRegistryApplied = true;
25
- }
26
- catch {
27
- }
28
- }
29
- let deepLinkListenerInstalled = false;
30
- currentDeepLinkSub?.remove?.();
31
- currentDeepLinkSub = undefined;
32
- let linking;
33
- try {
34
- linking = deps.linking ?? loadLinking();
35
- }
36
- catch {
37
- linking = undefined;
38
- }
39
- if (linking && typeof linking.addEventListener === "function") {
40
- const sub = linking.addEventListener("url", (event) => {
41
- if (typeof event?.url === "string") {
42
- handleCeraphDeepLink(event.url);
43
- }
44
- });
45
- currentDeepLinkSub = sub;
46
- deepLinkListenerInstalled = true;
47
- }
48
- const signalCapture = installSignalCapture();
49
- let keepAwakeActivated = false;
50
- const keepAwakeBinding = deps.keepAwake === undefined
51
- ? {
52
- enable: () => enableKeepAwake(),
53
- disable: () => disableKeepAwake(),
54
- }
55
- : deps.keepAwake ?? { enable: () => ({ applied: false }), disable: () => undefined };
56
- try {
57
- const res = keepAwakeBinding.enable();
58
- keepAwakeActivated = res.applied;
59
- }
60
- catch {
61
- keepAwakeActivated = false;
62
- }
63
- let appStateListenerInstalled = false;
64
- currentAppStateSub?.remove?.();
65
- currentAppStateSub = undefined;
66
- let appState;
67
- try {
68
- appState = deps.appState === undefined ? loadAppState() : deps.appState;
69
- }
70
- catch {
71
- appState = null;
72
- }
73
- if (appState && typeof appState.addEventListener === "function") {
74
- const sub = appState.addEventListener("change", (state) => {
75
- if (state === "active") {
76
- try {
77
- const res = keepAwakeBinding.enable();
78
- keepAwakeActivated = res.applied;
79
- }
80
- catch {
81
- }
82
- }
83
- else {
84
- try {
85
- keepAwakeBinding.disable();
86
- }
87
- catch {
88
- }
89
- }
90
- });
91
- currentAppStateSub = sub;
92
- appStateListenerInstalled = true;
93
- }
94
- return {
95
- cameraRegistryApplied,
96
- deepLinkListenerInstalled,
97
- signalCapture,
98
- keepAwakeActivated,
99
- appStateListenerInstalled,
100
- };
101
- }
102
- function loadGeneratedRegistry() {
103
- const req = globalThis.require;
104
- if (typeof req !== "function")
105
- return null;
106
- const candidates = [
107
- "../.ceraph/camera-images/_registry",
108
- "./.ceraph/camera-images/_registry",
109
- ];
110
- for (const id of candidates) {
111
- try {
112
- const mod = req(id);
113
- if (mod && typeof mod.applyCameraImageRegistry === "function") {
114
- return mod.applyCameraImageRegistry;
115
- }
116
- }
117
- catch {
118
- }
119
- }
120
- return null;
121
- }
122
- function loadLinking() {
123
- const req = globalThis.require;
124
- if (typeof req !== "function")
125
- return undefined;
126
- const mod = req("react-native");
127
- return mod?.Linking;
128
- }
129
- function loadAppState() {
130
- const req = globalThis.require;
131
- if (typeof req !== "function")
132
- return undefined;
133
- const mod = req("react-native");
134
- return mod?.AppState;
135
- }
136
- export function _resetForTesting() {
137
- currentDeepLinkSub?.remove?.();
138
- currentDeepLinkSub = undefined;
139
- currentAppStateSub?.remove?.();
140
- currentAppStateSub = undefined;
141
- }
1
+ import{AppState as a,Linking as b}from'react-native';import{installAsyncStorageBootObserver}from'./async-storage-ops.js';import{handleCeraphDeepLink}from'./deep-link.js';import{isDevRuntime}from'./dev-guard.js';import{disableKeepAwake,enableKeepAwake}from'./keep-awake.js';import{installSignalCapture}from'./signal-capture.js';import{postSignal}from'./signal-transport.js';let currentDeepLinkSub,currentAppStateSub;export function installCeraph(c={}){if(!isDevRuntime())return{'cameraRegistryApplied':![],'deepLinkListenerInstalled':![],'signalCapture':null,'keepAwakeActivated':![],'appStateListenerInstalled':![],'asyncStorageObserverInstalled':![],'testidSentinelPosted':![]};let d=![];const e=c['applyCameraImageRegistry']===undefined?loadGeneratedRegistry():c['applyCameraImageRegistry'];if(e)try{e(),d=!![];}catch{}let f=![];currentDeepLinkSub?.['remove']?.(),currentDeepLinkSub=undefined;let g;try{g=c['linking']??b;}catch{g=undefined;}if(g&&typeof g['addEventListener']==='function'){const q=g['addEventListener']('url',r=>{typeof r?.['url']==='string'&&handleCeraphDeepLink(r['url']);});currentDeepLinkSub=q,f=!![];}const h=installSignalCapture();let i=![];const j=c['keepAwake']===undefined?{'enable':()=>enableKeepAwake(),'disable':()=>disableKeepAwake()}:c['keepAwake']??{'enable':()=>({'applied':![]}),'disable':()=>undefined};try{const r=j['enable']();i=r['applied'];}catch{i=![];}let k=![];currentAppStateSub?.['remove']?.(),currentAppStateSub=undefined;let l;try{l=c['appState']===undefined?a:c['appState'];}catch{l=null;}if(l&&typeof l['addEventListener']==='function'){const s=l['addEventListener']('change',t=>{if(t==='active')try{const u=j['enable']();i=u['applied'];}catch{}else try{j['disable']();}catch{}});currentAppStateSub=s,k=!![];}let m=![];const n=c['installAsyncStorageObserver']===undefined?()=>installAsyncStorageBootObserver():c['installAsyncStorageObserver'];if(n)try{const t=n();m=t['installed'];}catch{m=![];}let o=![];const p=c['readTestidConfig']===undefined?loadTestidConfig:c['readTestidConfig'];if(p)try{const u=p();if(u&&typeof u==='object'){const v=typeof u['pluginVersion']==='string'?u['pluginVersion']:undefined,w=typeof u['babelConfigHash']==='string'?u['babelConfigHash']:undefined;(v!==undefined||w!==undefined)&&(void postSignal({'kind':'testid-sentinel','message':'testid-sentinel','timestampMs':Date['now'](),'pluginVersion':v,'babelConfigHash':w}),o=!![]);}}catch{o=![];}return{'cameraRegistryApplied':d,'deepLinkListenerInstalled':f,'signalCapture':h,'keepAwakeActivated':i,'appStateListenerInstalled':k,'asyncStorageObserverInstalled':m,'testidSentinelPosted':o};}function loadGeneratedRegistry(){try{const c=require('../.ceraph/camera-images/_registry');if(c&&typeof c['applyCameraImageRegistry']==='function')return c['applyCameraImageRegistry'];}catch{}try{const d=require('./.ceraph/camera-images/_registry');if(d&&typeof d['applyCameraImageRegistry']==='function')return d['applyCameraImageRegistry'];}catch{}return null;}function loadTestidConfig(){try{const c=require('../.ceraph/testid-config.json');if(c&&typeof c==='object')return{'pluginVersion':c['pluginVersion'],'babelConfigHash':c['babelConfigHash']};}catch{}try{const d=require('./.ceraph/testid-config.json');if(d&&typeof d==='object')return{'pluginVersion':d['pluginVersion'],'babelConfigHash':d['babelConfigHash']};}catch{}return null;}export function _resetForTesting(){currentDeepLinkSub?.['remove']?.(),currentDeepLinkSub=undefined,currentAppStateSub?.['remove']?.(),currentAppStateSub=undefined;}
@@ -1,62 +1 @@
1
- import { createElement, forwardRef, useImperativeHandle, } from "react";
2
- import { View, Image } from "react-native";
3
- import { getCurrentTestImage, selectTestImageKey } from "./config.js";
4
- import { isDevRuntime } from "./dev-guard.js";
5
- function resolveTestImageUri(source) {
6
- if (typeof source === "number") {
7
- const resolved = Image.resolveAssetSource(source);
8
- return resolved?.uri ?? "";
9
- }
10
- if (Array.isArray(source)) {
11
- const first = source[0];
12
- return first ? first.uri : "";
13
- }
14
- return source.uri;
15
- }
16
- export function buildTakePictureOverride() {
17
- if (!isDevRuntime())
18
- return null;
19
- if (getCurrentTestImage() === null)
20
- return null;
21
- return async () => {
22
- const live = getCurrentTestImage();
23
- if (!live) {
24
- return { uri: "", width: 0, height: 0, base64: undefined };
25
- }
26
- return {
27
- uri: resolveTestImageUri(live),
28
- width: 0,
29
- height: 0,
30
- base64: undefined,
31
- };
32
- };
33
- }
34
- export const CeraphCamera = forwardRef(function CeraphCamera(props, ref) {
35
- if (isDevRuntime() &&
36
- typeof props.imageKey === "string" &&
37
- props.imageKey.length > 0 &&
38
- !props.imageKey.startsWith("@")) {
39
- selectTestImageKey(props.imageKey);
40
- }
41
- const override = buildTakePictureOverride();
42
- useImperativeHandle(override !== null ? ref : null, () => ({ takePictureAsync: override }), [override]);
43
- if (override !== null) {
44
- const image = getCurrentTestImage();
45
- const imageElement = image != null
46
- ? createElement(Image, {
47
- key: "ceraph-test-image",
48
- source: image,
49
- style: { width: "100%", height: "100%" },
50
- resizeMode: "cover",
51
- })
52
- : null;
53
- return createElement(View, {
54
- style: props.style,
55
- children: [imageElement, props.children],
56
- });
57
- }
58
- const expoCamera = require("expo-camera");
59
- const CameraView = expoCamera.CameraView;
60
- return createElement(CameraView, { ...props, ref });
61
- });
62
- CeraphCamera.displayName = "CeraphCamera";
1
+ import{createElement,forwardRef,useImperativeHandle}from'react';import{View,Image}from'react-native';import{getCurrentTestImage,selectTestImageKey}from'./config.js';import{isDevRuntime}from'./dev-guard.js';function resolveTestImage(a){if(typeof a==='number'){const c=Image['resolveAssetSource'](a);return{'uri':c?.['uri']??'','width':c?.['width']??0x0,'height':c?.['height']??0x0};}if(Array['isArray'](a)){const d=a[0x0];return{'uri':d?.['uri']??'','width':d?.['width']??0x0,'height':d?.['height']??0x0};}const b=a;return{'uri':b['uri'],'width':b['width']??0x0,'height':b['height']??0x0};}export function buildTakePictureOverride(){if(!isDevRuntime())return null;if(getCurrentTestImage()===null)return null;return async()=>{const a=getCurrentTestImage();if(!a)return{'uri':'','width':0x0,'height':0x0,'base64':undefined};const {uri:b,width:c,height:d}=resolveTestImage(a);return{'uri':b,'width':c,'height':d,'base64':undefined};};}export const CeraphCamera=forwardRef(function CeraphCamera(a,b){isDevRuntime()&&typeof a['imageKey']==='string'&&a['imageKey']['length']>0x0&&!a['imageKey']['startsWith']('@')&&selectTestImageKey(a['imageKey']);const c=buildTakePictureOverride();useImperativeHandle(c!==null?b:null,()=>({'takePictureAsync':c}),[c]);if(c!==null){const f=getCurrentTestImage(),g=f!=null?createElement(Image,{'key':'ceraph-test-image','source':f,'style':{'width':'100%','height':'100%'},'resizeMode':'cover'}):null;return createElement(View,{'style':a['style'],'children':[g,a['children']]});}let d;try{d=require('expo-camera');}catch{d=null;}if(!d)throw new Error('[ceraph]\x20CeraphCamera\x20reached\x20its\x20production\x20branch\x20but\x20'+'expo-camera\x20is\x20not\x20installed.\x20Install\x20expo-camera,\x20or\x20remove\x20'+'the\x20CeraphCamera\x20usage\x20(npx\x20@ceraph/react-native-mcp\x20uninstall).');const e=d['CameraView'];return createElement(e,{...a,'ref':b});});CeraphCamera['displayName']='CeraphCamera';
@@ -0,0 +1,18 @@
1
+ export interface CommandPollOptions {
2
+ host?: string;
3
+ port?: number;
4
+ intervalMs?: number;
5
+ onReset?: () => Promise<{
6
+ ok: boolean;
7
+ detail?: string;
8
+ }>;
9
+ onReload?: () => {
10
+ ok: boolean;
11
+ detail?: string;
12
+ };
13
+ }
14
+ export interface InstallCommandPollResult {
15
+ installed: boolean;
16
+ uninstall: () => void;
17
+ }
18
+ export declare function installCommandPoll(opts?: CommandPollOptions): InstallCommandPollResult;
@@ -0,0 +1 @@
1
+ import{isDevRuntime}from'./dev-guard.js';import{clearAppStorage}from'./reset.js';import{triggerJsReload}from'./reload.js';const DEFAULT_HOST='localhost',DEFAULT_PORT=0x1fa5,DEFAULT_INTERVAL_MS=0x3e8,REQUEST_TIMEOUT_MS=0x5dc;function resolveEndpoint(a){let b,c;if(typeof globalThis!=='undefined'){const f=globalThis['process'];b=f?.['env']?.['CERAPH_SIGNAL_HOST'],c=f?.['env']?.['CERAPH_SIGNAL_PORT'];}const d=a['host']??b??DEFAULT_HOST,e=a['port']??(c?Number['parseInt'](c,0xa):DEFAULT_PORT);return{'host':d,'port':Number['isFinite'](e)?e:DEFAULT_PORT};}function rawFetch(){const a=globalThis['fetch'];return a?.['__ceraphOriginalFetch']??a;}async function defaultReset(){const a=await clearAppStorage();return{'ok':a['cleared'],'detail':a['reason']};}function defaultReload(){const a=triggerJsReload();return{'ok':a,'detail':a?undefined:'DevSettings.reload\x20unavailable'};}export function installCommandPoll(a={}){if(!isDevRuntime())return{'installed':![],'uninstall':()=>undefined};const {host:b,port:c}=resolveEndpoint(a),d=a['intervalMs']??DEFAULT_INTERVAL_MS,e='http://'+b+':'+c,f=a['onReset']??defaultReset,g=a['onReload']??defaultReload;let h=![],i=![];const j=async n=>{const o=rawFetch();if(typeof o!=='function')return;try{const p=new AbortController(),q=setTimeout(()=>p['abort'](),REQUEST_TIMEOUT_MS);try{await o(e+'/commands/ack',{'method':'POST','headers':{'Content-Type':'application/json'},'body':JSON['stringify'](n),'signal':p['signal']});}finally{clearTimeout(q);}}catch{}},k=async n=>{let o;try{o=n['type']==='reset'?await f():n['type']==='reload'?g():{'ok':![],'detail':'unknown\x20command\x20type'};}catch(p){o={'ok':![],'detail':p?.['message']??'handler\x20threw'};}await j({'id':n['id'],'ok':o['ok'],'detail':o['detail']});},l=async()=>{if(h||i)return;i=!![];try{const n=rawFetch();if(typeof n!=='function')return;const o=new AbortController(),p=setTimeout(()=>o['abort'](),REQUEST_TIMEOUT_MS);let q;try{q=await n(e+'/commands',{'method':'GET','signal':o['signal']});}finally{clearTimeout(p);}if(!q['ok'])return;const r=await q['json'](),s=Array['isArray'](r?.['commands'])?r['commands']:[];for(const u of s){if(u&&typeof u['id']==='string')await k(u);}}catch{}finally{i=![];}},m=setInterval(()=>{void l();},d);return m['unref']?.(),{'installed':!![],'uninstall':()=>{h=!![],clearInterval(m);}};}
@@ -1,56 +1 @@
1
- const registry = new Map();
2
- let currentKey = null;
3
- const DEFAULT_KEY = "default";
4
- let bundledDefaultRegistered = false;
5
- function ensureBundledDefault() {
6
- if (bundledDefaultRegistered)
7
- return;
8
- bundledDefaultRegistered = true;
9
- const req = globalThis.require;
10
- if (typeof req !== "function")
11
- return;
12
- try {
13
- const asset = req("../../assets/default.png");
14
- if (asset != null && !registry.has(DEFAULT_KEY)) {
15
- registry.set(DEFAULT_KEY, asset);
16
- }
17
- }
18
- catch {
19
- }
20
- }
21
- export function configureTestImage(keyOrSource, source) {
22
- if (source === undefined) {
23
- registry.set(DEFAULT_KEY, keyOrSource);
24
- return;
25
- }
26
- if (typeof keyOrSource !== "string") {
27
- throw new Error("configureTestImage: key must be a string when 2 args are passed");
28
- }
29
- registry.set(keyOrSource, source);
30
- }
31
- export function selectTestImageKey(key) {
32
- currentKey = key;
33
- }
34
- export function getCurrentTestImage() {
35
- if (currentKey && registry.has(currentKey)) {
36
- return registry.get(currentKey) ?? null;
37
- }
38
- if (!registry.has(DEFAULT_KEY)) {
39
- ensureBundledDefault();
40
- }
41
- if (registry.has(DEFAULT_KEY)) {
42
- return registry.get(DEFAULT_KEY) ?? null;
43
- }
44
- return null;
45
- }
46
- export function _resetForTesting() {
47
- registry.clear();
48
- currentKey = null;
49
- bundledDefaultRegistered = false;
50
- }
51
- export function _registerBundledDefaultForTesting(source) {
52
- bundledDefaultRegistered = true;
53
- if (!registry.has(DEFAULT_KEY)) {
54
- registry.set(DEFAULT_KEY, source);
55
- }
56
- }
1
+ const registry=new Map();let currentKey=null;const DEFAULT_KEY='default';let bundledDefaultRegistered=![];function ensureBundledDefault(){if(bundledDefaultRegistered)return;bundledDefaultRegistered=!![];try{const a=require('../../assets/default.png');a!=null&&!registry['has'](DEFAULT_KEY)&&registry['set'](DEFAULT_KEY,a);}catch{}}export function configureTestImage(a,b){if(b===undefined){registry['set'](DEFAULT_KEY,a);return;}if(typeof a!=='string')throw new Error('configureTestImage:\x20key\x20must\x20be\x20a\x20string\x20when\x202\x20args\x20are\x20passed');registry['set'](a,b);}export function selectTestImageKey(a){currentKey=a;}export function getCurrentTestImage(){if(currentKey&&registry['has'](currentKey))return registry['get'](currentKey)??null;!registry['has'](DEFAULT_KEY)&&ensureBundledDefault();if(registry['has'](DEFAULT_KEY))return registry['get'](DEFAULT_KEY)??null;return null;}export function _resetForTesting(){registry['clear'](),currentKey=null,bundledDefaultRegistered=![];}export function _registerBundledDefaultForTesting(a){bundledDefaultRegistered=!![],!registry['has'](DEFAULT_KEY)&&registry['set'](DEFAULT_KEY,a);}
@@ -0,0 +1,16 @@
1
+ import { type TransportOptions } from "./signal-transport.js";
2
+ type ConsoleErrorFn = (...args: unknown[]) => void;
3
+ interface ConsoleLike {
4
+ error: ConsoleErrorFn;
5
+ }
6
+ export interface InstallConsoleCaptureOptions {
7
+ transport?: TransportOptions;
8
+ globalRef?: {
9
+ console?: ConsoleLike;
10
+ };
11
+ }
12
+ export declare function installConsoleCapture(opts?: InstallConsoleCaptureOptions): boolean;
13
+ export declare function _uninstallForTesting(globalRef?: {
14
+ console?: ConsoleLike;
15
+ }): void;
16
+ export {};
@@ -0,0 +1 @@
1
+ import{isDevRuntime}from'./dev-guard.js';import{postSignal}from'./signal-transport.js';const MAX_CONSOLE_SIGNALS=0x32,MAX_MESSAGE_CHARS=0x7d0;let emitting=![],emittedCount=0x0,capNoticeSent=![];export function installConsoleCapture(a={}){if(!isDevRuntime())return![];const b=a['globalRef']??globalThis,c=b['console'];if(!c||typeof c['error']!=='function')return![];const d=c['error'],e=d['__ceraphOriginalConsoleError']??d,f=function(...g){const h=e['apply'](this,g);try{if(!emitting){emitting=!![];try{emitConsoleError(g,a['transport']);}finally{emitting=![];}}}catch{}return h;};return f['__ceraphOriginalConsoleError']=e,c['error']=f,!![];}function emitConsoleError(a,b){if(emittedCount>=MAX_CONSOLE_SIGNALS){!capNoticeSent&&(capNoticeSent=!![],void postSignal({'kind':'console-error','message':'[ceraph]\x20console.error\x20capture\x20capped\x20at\x20'+MAX_CONSOLE_SIGNALS+'\x20this\x20session;\x20further\x20console\x20errors\x20are\x20visible\x20in\x20Metro\x20but\x20not\x20signalled.','timestampMs':Date['now']()},b));return;}emittedCount++,void postSignal({'kind':'console-error','message':serializeArgs(a),'timestampMs':Date['now']()},b);}function serializeArgs(a){const b=[];for(const d of a){b['push'](serializeOne(d));}const c=b['join']('\x20')['trim']()||'<empty\x20console.error>';return c['length']>MAX_MESSAGE_CHARS?c['slice'](0x0,MAX_MESSAGE_CHARS)+'…':c;}function serializeOne(a){if(typeof a==='string')return a;if(a instanceof Error)return a['stack']??a['name']+':\x20'+a['message'];if(a===null)return'null';if(a===undefined)return'undefined';if(typeof a==='object')try{return JSON['stringify'](a);}catch{}try{return String(a);}catch{return'<unstringifiable>';}}export function _uninstallForTesting(a=globalThis){const b=a['console'],c=b?.['error'];b&&c?.['__ceraphOriginalConsoleError']&&(b['error']=c['__ceraphOriginalConsoleError']),emitting=![],emittedCount=0x0,capNoticeSent=![];}
@@ -1,25 +1 @@
1
- import { selectTestImageKey } from "./config.js";
2
- const MAX_KEY_LEN = 255;
3
- export function handleCeraphDeepLink(url) {
4
- if (!url)
5
- return false;
6
- let parsed;
7
- try {
8
- parsed = new URL(url);
9
- }
10
- catch {
11
- return false;
12
- }
13
- if (parsed.protocol !== "ceraph:")
14
- return false;
15
- const action = parsed.hostname;
16
- if (action === "test-image") {
17
- const key = parsed.searchParams.get("key");
18
- if (key && key.length > 0 && key.length <= MAX_KEY_LEN) {
19
- selectTestImageKey(key);
20
- return true;
21
- }
22
- return false;
23
- }
24
- return false;
25
- }
1
+ import{deleteKeys}from'./async-storage-ops.js';import{selectTestImageKey}from'./config.js';import{postSignal}from'./signal-transport.js';const MAX_KEY_LEN=0xff,MAX_STORAGE_KEYS=0x32,MAX_STORAGE_KEY_LEN=0x200;export function handleCeraphDeepLink(a){if(!a)return![];let b;try{b=new URL(a);}catch{return![];}if(b['protocol']!=='ceraph:')return![];const c=b['hostname'];if(c==='test-image'){const d=b['searchParams']['get']('key');if(d&&d['length']>0x0&&d['length']<=MAX_KEY_LEN)return selectTestImageKey(d),!![];return![];}if(c==='storage')return void handleStorageDeepLink(b),!![];return![];}async function handleStorageDeepLink(a){const b=a['searchParams']['get']('op');if(b!=='delete')return;const c=a['searchParams']['get']('id')??undefined,d=a['searchParams']['get']('keys')??'',e=d['split'](',')['map'](j=>j['trim']())['filter'](j=>j['length']>0x0),f=e['length']>MAX_STORAGE_KEYS,g=e['some'](j=>j['length']>MAX_STORAGE_KEY_LEN);if(f||g){await postStorageAck({'success':![],'count':0x0,'keys':[],'requestId':c,'error':'exceeds\x20caps'});return;}const h=e['filter'](j=>j['length']<=MAX_STORAGE_KEY_LEN)['slice'](0x0,MAX_STORAGE_KEYS);if(h['length']===0x0){await postStorageAck({'success':!![],'count':0x0,'keys':[],'requestId':c});return;}const i=await deleteKeys(h);await postStorageAck({'success':i['cleared'],'count':i['cleared']?i['requested']:0x0,'keys':h,'requestId':c});}async function postStorageAck(a){const b=a['error']??'delete\x20failed';await postSignal({'kind':'storage-ack','message':a['success']?'delete\x20count='+a['count']:b,'timestampMs':Date['now'](),'storageAckSuccess':a['success'],'storageAckCount':a['count'],'storageAckKeys':a['keys'],...a['requestId']?{'storageAckRequestId':a['requestId']}:{}})['catch'](()=>undefined);}
@@ -1,3 +1 @@
1
- export function isDevRuntime() {
2
- return typeof __DEV__ !== "undefined" && __DEV__ === true;
3
- }
1
+ export function isDevRuntime(){return typeof __DEV__!=='undefined'&&__DEV__===!![];}
@@ -0,0 +1 @@
1
+ export declare function resolveDevServerHost(): string | undefined;
@@ -0,0 +1 @@
1
+ import{NativeModules}from'react-native';export function resolveDevServerHost(){try{const a=NativeModules?.['SourceCode'];if(!a)return undefined;const b=(typeof a['getConstants']==='function'?a['getConstants']()['scriptURL']:undefined)??a['scriptURL'];if(typeof b!=='string'||b['length']===0x0)return undefined;const c=/^https?:\/\/(\[[^\]]+\]|[^/:]+)(?::\d+)?\//['exec'](b);let d=c?.[0x1];return d&&d['startsWith']('[')&&d['endsWith'](']')&&(d=d['slice'](0x1,-0x1)),d&&d['length']>0x0?d:undefined;}catch{return undefined;}}
@@ -1,66 +1 @@
1
- import { isDevRuntime } from "./dev-guard.js";
2
- import { postSignal } from "./signal-transport.js";
3
- let installed = false;
4
- export function installErrorHandler(opts = {}) {
5
- if (!isDevRuntime())
6
- return false;
7
- if (installed)
8
- return false;
9
- installed = true;
10
- const utils = opts.errorUtils ??
11
- globalThis.ErrorUtils;
12
- if (utils && typeof utils.setGlobalHandler === "function") {
13
- const previous = utils.getGlobalHandler?.();
14
- utils.setGlobalHandler((error, isFatal) => {
15
- void postSignal({
16
- kind: "js-error",
17
- message: error?.message ?? String(error),
18
- stack: error?.stack,
19
- timestampMs: Date.now(),
20
- }, opts.transport);
21
- try {
22
- previous?.(error, isFatal);
23
- }
24
- catch {
25
- }
26
- });
27
- }
28
- const hermes = opts.hermesInternal ??
29
- globalThis.HermesInternal;
30
- if (hermes && typeof hermes.enablePromiseRejectionTracker === "function") {
31
- hermes.enablePromiseRejectionTracker({
32
- allRejections: true,
33
- onUnhandled: (_id, error) => {
34
- const message = extractMessage(error);
35
- const stack = extractStack(error);
36
- void postSignal({
37
- kind: "unhandled-rejection",
38
- message,
39
- stack,
40
- timestampMs: Date.now(),
41
- }, opts.transport);
42
- },
43
- });
44
- }
45
- return true;
46
- }
47
- function extractMessage(error) {
48
- if (error instanceof Error)
49
- return error.message;
50
- if (typeof error === "string")
51
- return error;
52
- try {
53
- return JSON.stringify(error);
54
- }
55
- catch {
56
- return String(error);
57
- }
58
- }
59
- function extractStack(error) {
60
- if (error instanceof Error)
61
- return error.stack;
62
- return undefined;
63
- }
64
- export function _resetForTesting() {
65
- installed = false;
66
- }
1
+ import{isDevRuntime}from'./dev-guard.js';import{postSignal}from'./signal-transport.js';let installed=![];export function installErrorHandler(a={}){if(!isDevRuntime())return![];if(installed)return![];installed=!![];const b=a['errorUtils']??globalThis['ErrorUtils'];if(b&&typeof b['setGlobalHandler']==='function'){const d=b['getGlobalHandler']?.();b['setGlobalHandler']((e,f)=>{void postSignal({'kind':'js-error','message':e?.['message']??String(e),'stack':e?.['stack'],'timestampMs':Date['now']()},a['transport']);try{d?.(e,f);}catch{}});}const c=a['hermesInternal']??globalThis['HermesInternal'];return c&&typeof c['enablePromiseRejectionTracker']==='function'&&c['enablePromiseRejectionTracker']({'allRejections':!![],'onUnhandled':(e,f)=>{const g=extractMessage(f),h=extractStack(f);void postSignal({'kind':'unhandled-rejection','message':g,'stack':h,'timestampMs':Date['now']()},a['transport']);}}),!![];}function extractMessage(a){if(a instanceof Error)return a['message'];if(typeof a==='string')return a;try{return JSON['stringify'](a);}catch{return String(a);}}function extractStack(a){if(a instanceof Error)return a['stack'];return undefined;}export function _resetForTesting(){installed=![];}
@@ -1,93 +1 @@
1
- import { isDevRuntime } from "./dev-guard.js";
2
- import { postSignal } from "./signal-transport.js";
3
- export function installFetchInterceptor(opts = {}) {
4
- if (!isDevRuntime())
5
- return false;
6
- const target = opts.globalRef ?? globalThis;
7
- const current = target.fetch;
8
- if (typeof current !== "function")
9
- return false;
10
- const original = current.__ceraphOriginalFetch ?? current;
11
- const wrapper = async (input, init) => {
12
- const url = extractUrl(input);
13
- const method = extractMethod(input, init);
14
- const startedAt = Date.now();
15
- try {
16
- const response = await original(input, init);
17
- const durationMs = Date.now() - startedAt;
18
- const status = response.status;
19
- if (status >= 500) {
20
- void postSignal({
21
- kind: "network-error",
22
- message: `${method} ${url} → ${status}`,
23
- timestampMs: Date.now(),
24
- url,
25
- status,
26
- method,
27
- durationMs,
28
- }, opts.transport);
29
- }
30
- else if (status >= 400) {
31
- void postSignal({
32
- kind: "network-4xx",
33
- message: `${method} ${url} → ${status}`,
34
- timestampMs: Date.now(),
35
- url,
36
- status,
37
- method,
38
- durationMs,
39
- }, opts.transport);
40
- }
41
- return response;
42
- }
43
- catch (err) {
44
- const durationMs = Date.now() - startedAt;
45
- void postSignal({
46
- kind: "network-error",
47
- message: `${method} ${url} failed: ${err?.message ?? String(err)}`,
48
- stack: err?.stack,
49
- timestampMs: Date.now(),
50
- url,
51
- method,
52
- durationMs,
53
- }, opts.transport);
54
- throw err;
55
- }
56
- };
57
- wrapper.__ceraphOriginalFetch = original;
58
- target.fetch = wrapper;
59
- return true;
60
- }
61
- function extractUrl(input) {
62
- if (typeof input === "string")
63
- return input;
64
- if (input && typeof input === "object") {
65
- const maybeUrl = input.url;
66
- if (typeof maybeUrl === "string")
67
- return maybeUrl;
68
- if (typeof input.toString === "function") {
69
- try {
70
- return String(input);
71
- }
72
- catch {
73
- return "<unknown-url>";
74
- }
75
- }
76
- }
77
- return "<unknown-url>";
78
- }
79
- function extractMethod(input, init) {
80
- const fromInit = init?.method;
81
- if (typeof fromInit === "string")
82
- return fromInit.toUpperCase();
83
- const fromRequest = input?.method;
84
- if (typeof fromRequest === "string")
85
- return fromRequest.toUpperCase();
86
- return "GET";
87
- }
88
- export function _uninstallForTesting(globalRef = globalThis) {
89
- const current = globalRef.fetch;
90
- if (current?.__ceraphOriginalFetch) {
91
- globalRef.fetch = current.__ceraphOriginalFetch;
92
- }
93
- }
1
+ import{isDevRuntime}from'./dev-guard.js';import{beginFetchInvocation,endFetchInvocation}from'./network-ownership.js';import{postSignal}from'./signal-transport.js';const MUTATING_METHODS=new Set(['POST','PUT','PATCH','DELETE']);export function installFetchInterceptor(a={}){if(!isDevRuntime())return![];const b=a['globalRef']??globalThis,c=b['fetch'];if(typeof c!=='function')return![];const d=c['__ceraphOriginalFetch']??c,e=async(f,g)=>{const h=extractUrl(f),i=extractMethod(f,g),j=Date['now']();let k;beginFetchInvocation();try{k=d(f,g);}catch(l){k=Promise['reject'](l);}finally{endFetchInvocation();}try{const m=await k,n=Date['now']()-j,o=m['status'];if(o>=0x1f4)void postSignal({'kind':'network-error','message':i+'\x20'+h+'\x20→\x20'+o,'timestampMs':Date['now'](),'url':h,'status':o,'method':i,'durationMs':n},a['transport']);else{if(o>=0x190)void postSignal({'kind':'network-4xx','message':i+'\x20'+h+'\x20→\x20'+o,'timestampMs':Date['now'](),'url':h,'status':o,'method':i,'durationMs':n},a['transport']);else MUTATING_METHODS['has'](i)&&void postSignal({'kind':'mutation-fired','message':i+'\x20'+h+'\x20→\x20'+o,'timestampMs':Date['now'](),'url':h,'status':o,'method':i,'durationMs':n},a['transport']);}return m;}catch(p){const q=Date['now']()-j;void postSignal({'kind':'network-error','message':i+'\x20'+h+'\x20failed:\x20'+(p?.['message']??String(p)),'stack':p?.['stack'],'timestampMs':Date['now'](),'url':h,'method':i,'durationMs':q},a['transport']);throw p;}};return e['__ceraphOriginalFetch']=d,b['fetch']=e,!![];}function extractUrl(a){if(typeof a==='string')return a;if(a&&typeof a==='object'){const b=a['url'];if(typeof b==='string')return b;if(typeof a['toString']==='function')try{return String(a);}catch{return'<unknown-url>';}}return'<unknown-url>';}function extractMethod(a,b){const c=b?.['method'];if(typeof c==='string')return c['toUpperCase']();const d=a?.['method'];if(typeof d==='string')return d['toUpperCase']();return'GET';}export function _uninstallForTesting(a=globalThis){const b=a['fetch'];b?.['__ceraphOriginalFetch']&&(a['fetch']=b['__ceraphOriginalFetch']);}
@@ -3,4 +3,7 @@ export { CeraphCamera, type CeraphCameraProps } from "./camera.js";
3
3
  export { configureTestImage, getCurrentTestImage, selectTestImageKey, } from "./config.js";
4
4
  export { handleCeraphDeepLink } from "./deep-link.js";
5
5
  export { installSignalCapture, type InstallSignalCaptureOptions, type InstallSignalCaptureResult, } from "./signal-capture.js";
6
+ export { installOptimisticObserver, notifyOptimisticUpdate, type OptimisticObserverOptions, } from "./optimistic-observer.js";
6
7
  export { installReloadListener, triggerJsReload } from "./reload.js";
8
+ export { installCommandPoll, type CommandPollOptions, type InstallCommandPollResult, } from "./command-poll.js";
9
+ export { clearAppStorage, installResetListener, registerResetHook, type ClearAppStorageResult, } from "./reset.js";
@@ -1,6 +1 @@
1
- export { installCeraph, } from "./boot.js";
2
- export { CeraphCamera } from "./camera.js";
3
- export { configureTestImage, getCurrentTestImage, selectTestImageKey, } from "./config.js";
4
- export { handleCeraphDeepLink } from "./deep-link.js";
5
- export { installSignalCapture, } from "./signal-capture.js";
6
- export { installReloadListener, triggerJsReload } from "./reload.js";
1
+ export{installCeraph}from'./boot.js';export{CeraphCamera}from'./camera.js';export{configureTestImage,getCurrentTestImage,selectTestImageKey}from'./config.js';export{handleCeraphDeepLink}from'./deep-link.js';export{installSignalCapture}from'./signal-capture.js';export{installOptimisticObserver,notifyOptimisticUpdate}from'./optimistic-observer.js';export{installReloadListener,triggerJsReload}from'./reload.js';export{installCommandPoll}from'./command-poll.js';export{clearAppStorage,installResetListener,registerResetHook}from'./reset.js';