@sudo-ping-pong/prism-expo-client 0.1.1

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 (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +182 -0
  3. package/dist/buffer.d.ts +8 -0
  4. package/dist/buffer.d.ts.map +1 -0
  5. package/dist/buffer.js +19 -0
  6. package/dist/buffer.js.map +1 -0
  7. package/dist/capture.d.ts +5 -0
  8. package/dist/capture.d.ts.map +1 -0
  9. package/dist/capture.js +36 -0
  10. package/dist/capture.js.map +1 -0
  11. package/dist/command-handler.d.ts +2 -0
  12. package/dist/command-handler.d.ts.map +1 -0
  13. package/dist/command-handler.js +14 -0
  14. package/dist/command-handler.js.map +1 -0
  15. package/dist/config.d.ts +22 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/config.js +15 -0
  18. package/dist/config.js.map +1 -0
  19. package/dist/index.d.ts +38 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +103 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/middleware/redux.d.ts +28 -0
  24. package/dist/middleware/redux.d.ts.map +1 -0
  25. package/dist/middleware/redux.js +94 -0
  26. package/dist/middleware/redux.js.map +1 -0
  27. package/dist/middleware/zustand.d.ts +11 -0
  28. package/dist/middleware/zustand.d.ts.map +1 -0
  29. package/dist/middleware/zustand.js +37 -0
  30. package/dist/middleware/zustand.js.map +1 -0
  31. package/dist/patches/axios.d.ts +4 -0
  32. package/dist/patches/axios.d.ts.map +1 -0
  33. package/dist/patches/axios.js +140 -0
  34. package/dist/patches/axios.js.map +1 -0
  35. package/dist/patches/capture-guard.d.ts +5 -0
  36. package/dist/patches/capture-guard.d.ts.map +1 -0
  37. package/dist/patches/capture-guard.js +24 -0
  38. package/dist/patches/capture-guard.js.map +1 -0
  39. package/dist/patches/console.d.ts +2 -0
  40. package/dist/patches/console.d.ts.map +1 -0
  41. package/dist/patches/console.js +21 -0
  42. package/dist/patches/console.js.map +1 -0
  43. package/dist/patches/fetch.d.ts +4 -0
  44. package/dist/patches/fetch.d.ts.map +1 -0
  45. package/dist/patches/fetch.js +106 -0
  46. package/dist/patches/fetch.js.map +1 -0
  47. package/dist/patches/xhr.d.ts +2 -0
  48. package/dist/patches/xhr.d.ts.map +1 -0
  49. package/dist/patches/xhr.js +74 -0
  50. package/dist/patches/xhr.js.map +1 -0
  51. package/dist/profiler.d.ts +9 -0
  52. package/dist/profiler.d.ts.map +1 -0
  53. package/dist/profiler.js +19 -0
  54. package/dist/profiler.js.map +1 -0
  55. package/dist/transport-registry.d.ts +8 -0
  56. package/dist/transport-registry.d.ts.map +1 -0
  57. package/dist/transport-registry.js +11 -0
  58. package/dist/transport-registry.js.map +1 -0
  59. package/dist/transport.d.ts +38 -0
  60. package/dist/transport.d.ts.map +1 -0
  61. package/dist/transport.js +153 -0
  62. package/dist/transport.js.map +1 -0
  63. package/package.json +111 -0
  64. package/src/buffer.ts +23 -0
  65. package/src/capture.ts +40 -0
  66. package/src/command-handler.ts +15 -0
  67. package/src/config.ts +29 -0
  68. package/src/env.d.ts +1 -0
  69. package/src/index.ts +148 -0
  70. package/src/middleware/redux.ts +126 -0
  71. package/src/middleware/zustand.ts +58 -0
  72. package/src/patches/axios.ts +182 -0
  73. package/src/patches/capture-guard.ts +24 -0
  74. package/src/patches/console.ts +27 -0
  75. package/src/patches/fetch.ts +118 -0
  76. package/src/patches/xhr.ts +103 -0
  77. package/src/profiler.tsx +36 -0
  78. package/src/transport-registry.ts +20 -0
  79. package/src/transport.ts +198 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Syed Numan Ahmed
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,182 @@
1
+ # @prism/expo-client
2
+
3
+ Real-time debugging SDK for **Expo** and **React Native**. Streams network requests, console output, and Redux/Zustand state to **Prism DevTools** on your Mac.
4
+
5
+ ## Requirements
6
+
7
+ - Expo SDK 49+ or React Native 0.72+
8
+ - Prism DevTools macOS app (DMG) or `@prism/server` + desktop UI
9
+ - Device/simulator and Mac on the **same Wi‑Fi**
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ npm install @prism/expo-client
15
+ # or
16
+ pnpm add @prism/expo-client
17
+ # or
18
+ yarn add @prism/expo-client
19
+ ```
20
+
21
+ ## Quick start
22
+
23
+ 1. Open **Prism DevTools** on your Mac.
24
+ 2. Click **Connect App** and note your **LAN IP** (e.g. `192.168.1.100`).
25
+ 3. Initialize the SDK as early as possible in your app entry file:
26
+
27
+ ```ts
28
+ import { initPrismLocal, PrismProfiler } from '@prism/expo-client';
29
+
30
+ initPrismLocal('192.168.1.100');
31
+
32
+ export default function App() {
33
+ return (
34
+ <PrismProfiler id="AppRoot">
35
+ {/* your app */}
36
+ </PrismProfiler>
37
+ );
38
+ }
39
+ ```
40
+
41
+ `initPrismLocal` is a shortcut for connecting to Prism on port `8080` at the given host.
42
+
43
+ ### Manual host + port
44
+
45
+ ```ts
46
+ import { initPrism } from '@prism/expo-client';
47
+
48
+ initPrism({
49
+ host: '192.168.1.100',
50
+ port: 8080,
51
+ });
52
+ ```
53
+
54
+ ## What gets captured
55
+
56
+ | Stream | Default | Source |
57
+ |--------|---------|--------|
58
+ | Network | on | `fetch`, `XMLHttpRequest`, and `axios` (if installed) |
59
+ | Console | on | `console.log` / `warn` / `error` |
60
+ | State | opt-in | Redux or Zustand middleware |
61
+ | Performance | opt-in | `PrismProfiler` wrapper |
62
+
63
+ Dev-only by default (`__DEV__`). Pass `forceEnable: true` to run in production builds.
64
+
65
+ ## Redux + time travel
66
+
67
+ ```ts
68
+ import { configureStore } from '@reduxjs/toolkit';
69
+ import {
70
+ prismReduxMiddleware,
71
+ withPrismStateReplay,
72
+ registerPrismReduxStore,
73
+ } from '@prism/expo-client';
74
+
75
+ const store = configureStore({
76
+ reducer: withPrismStateReplay(rootReducer),
77
+ middleware: (gDM) => gDM().concat(prismReduxMiddleware('my-store')),
78
+ });
79
+
80
+ registerPrismReduxStore(store, 'my-store');
81
+ ```
82
+
83
+ In Prism DevTools → **State**, select an action and use **Replay Action** or **Jump to State**.
84
+
85
+ ## Zustand
86
+
87
+ ```ts
88
+ import { create } from 'zustand';
89
+ import { prismZustandMiddleware } from '@prism/expo-client';
90
+
91
+ const useStore = create(
92
+ prismZustandMiddleware('my-store')((set) => ({
93
+ count: 0,
94
+ increment: () => set((s) => ({ count: s.count + 1 })),
95
+ })),
96
+ );
97
+ ```
98
+
99
+ ## API
100
+
101
+ | Export | Description |
102
+ |--------|-------------|
103
+ | `initPrism(config)` | Connect with full options |
104
+ | `initPrismLocal(host, overrides?)` | Connect to Prism on LAN IP |
105
+ | `reconnectPrism(config)` | Change host/port without reinstalling patches |
106
+ | `destroyPrism()` | Disconnect and remove patches |
107
+ | `PrismProfiler` | Capture React render timings |
108
+ | `prismReduxMiddleware` | Redux action + state snapshots |
109
+ | `prismZustandMiddleware` | Zustand state snapshots |
110
+
111
+ ### Config options
112
+
113
+ ```ts
114
+ initPrism({
115
+ host: '192.168.1.100',
116
+ port: 8080, // default 8080
117
+ network: true, // fetch + XHR + axios (when installed)
118
+ logs: true, // console
119
+ forceEnable: false, // only __DEV__ when false
120
+ onConnect: () => {},
121
+ onDisconnect: () => {},
122
+ onError: (err) => {},
123
+ });
124
+ ```
125
+
126
+ ## Axios
127
+
128
+ Install axios in your app — Prism auto-patches the default instance and instances from `axios.create()`:
129
+
130
+ ```bash
131
+ pnpm add axios
132
+ ```
133
+
134
+ ```ts
135
+ import axios from 'axios';
136
+ import { initPrismLocal } from '@prism/expo-client';
137
+
138
+ initPrismLocal('192.168.1.100');
139
+
140
+ const { data } = await axios.get('https://api.example.com/users');
141
+ ```
142
+
143
+ Requests appear in Prism with initiator **AXIOS**. Duplicate fetch/XHR events are suppressed while axios handles the request.
144
+
145
+ To patch a specific axios module manually:
146
+
147
+ ```ts
148
+ import axios from 'axios';
149
+ import { initPrism, installAxiosPatch } from '@prism/expo-client';
150
+
151
+ initPrism({ host: '192.168.1.100' });
152
+ installAxiosPatch(axios);
153
+ ```
154
+
155
+ ## Subpath exports
156
+
157
+ ```ts
158
+ import { prismReduxMiddleware } from '@prism/expo-client/redux';
159
+ import { prismZustandMiddleware } from '@prism/expo-client/zustand';
160
+ import { PrismProfiler } from '@prism/expo-client/profiler';
161
+ ```
162
+
163
+ ## Troubleshooting
164
+
165
+ **Not connecting**
166
+
167
+ - Confirm Mac and device are on the same network.
168
+ - Use the LAN IP from Prism’s Connect sheet, not `localhost` (on a physical device).
169
+ - Check that port `8080` isn’t blocked by a firewall.
170
+
171
+ **No events in Prism**
172
+
173
+ - Call `initPrismLocal` before your app renders.
174
+ - Ensure you’re in a dev build, or pass `forceEnable: true`.
175
+
176
+ ## Related packages
177
+
178
+ - [`@prism/protocol`](https://www.npmjs.com/package/@prism/protocol) — shared wire types (dependency)
179
+
180
+ ## License
181
+
182
+ MIT © Prism DevTools
@@ -0,0 +1,8 @@
1
+ import type { PrismEnvelope } from '@sudo-ping-pong/prism-protocol';
2
+ export declare class EventBuffer {
3
+ private buffer;
4
+ push(envelope: PrismEnvelope): void;
5
+ drain(): PrismEnvelope[];
6
+ get size(): number;
7
+ }
8
+ //# sourceMappingURL=buffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buffer.d.ts","sourceRoot":"","sources":["../src/buffer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAGpE,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAuB;IAErC,IAAI,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAOnC,KAAK,IAAI,aAAa,EAAE;IAMxB,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
package/dist/buffer.js ADDED
@@ -0,0 +1,19 @@
1
+ import { PRISM_MAX_BUFFER_SIZE } from '@sudo-ping-pong/prism-protocol';
2
+ export class EventBuffer {
3
+ buffer = [];
4
+ push(envelope) {
5
+ if (this.buffer.length >= PRISM_MAX_BUFFER_SIZE) {
6
+ this.buffer.shift();
7
+ }
8
+ this.buffer.push(envelope);
9
+ }
10
+ drain() {
11
+ const items = [...this.buffer];
12
+ this.buffer = [];
13
+ return items;
14
+ }
15
+ get size() {
16
+ return this.buffer.length;
17
+ }
18
+ }
19
+ //# sourceMappingURL=buffer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buffer.js","sourceRoot":"","sources":["../src/buffer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAEvE,MAAM,OAAO,WAAW;IACd,MAAM,GAAoB,EAAE,CAAC;IAErC,IAAI,CAAC,QAAuB;QAC1B,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,qBAAqB,EAAE,CAAC;YAChD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK;QACH,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5B,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ import type { LogLevel, NetworkPayload, StatePayload } from '@sudo-ping-pong/prism-protocol';
2
+ export declare function captureLogEvent(level: LogLevel, args: unknown[]): void;
3
+ export declare function captureNetworkEvent(payload: NetworkPayload): void;
4
+ export declare function captureStateEvent(payload: StatePayload): void;
5
+ //# sourceMappingURL=capture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAc,cAAc,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAGzG,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAOtE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAEjE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAE7D"}
@@ -0,0 +1,36 @@
1
+ import { createEnvelope } from '@sudo-ping-pong/prism-protocol';
2
+ import { sendToPrism } from './transport-registry';
3
+ export function captureLogEvent(level, args) {
4
+ const payload = {
5
+ level,
6
+ args: serializeArgs(args),
7
+ stack: level === 'error' ? captureStack() : undefined,
8
+ };
9
+ sendToPrism(createEnvelope('LOG', payload));
10
+ }
11
+ export function captureNetworkEvent(payload) {
12
+ sendToPrism(createEnvelope('NETWORK', payload));
13
+ }
14
+ export function captureStateEvent(payload) {
15
+ sendToPrism(createEnvelope('STATE', payload));
16
+ }
17
+ function serializeArgs(args) {
18
+ return args.map((arg) => {
19
+ if (arg instanceof Error) {
20
+ return { name: arg.name, message: arg.message, stack: arg.stack };
21
+ }
22
+ try {
23
+ JSON.stringify(arg);
24
+ return arg;
25
+ }
26
+ catch {
27
+ return String(arg);
28
+ }
29
+ });
30
+ }
31
+ function captureStack() {
32
+ const err = new Error();
33
+ const lines = err.stack?.split('\n').slice(2);
34
+ return lines?.join('\n');
35
+ }
36
+ //# sourceMappingURL=capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.js","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEhE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,MAAM,UAAU,eAAe,CAAC,KAAe,EAAE,IAAe;IAC9D,MAAM,OAAO,GAAe;QAC1B,KAAK;QACL,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC;QACzB,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,SAAS;KACtD,CAAC;IACF,WAAW,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAuB;IACzD,WAAW,CAAC,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAqB;IACrD,WAAW,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,aAAa,CAAC,IAAe;IACpC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;QACpE,CAAC;QACD,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACpB,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;IACxB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9C,OAAO,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function handlePrismCommand(raw: unknown): void;
2
+ //# sourceMappingURL=command-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-handler.d.ts","sourceRoot":"","sources":["../src/command-handler.ts"],"names":[],"mappings":"AAGA,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAWrD"}
@@ -0,0 +1,14 @@
1
+ import { isPrismCommand } from '@sudo-ping-pong/prism-protocol';
2
+ import { dispatchPrismReduxCommand } from './middleware/redux';
3
+ export function handlePrismCommand(raw) {
4
+ if (!isPrismCommand(raw))
5
+ return;
6
+ if (raw.command === 'dispatch') {
7
+ dispatchPrismReduxCommand(raw.storeId, 'dispatch', raw.action);
8
+ return;
9
+ }
10
+ if (raw.command === 'replace_state') {
11
+ dispatchPrismReduxCommand(raw.storeId, 'replace_state', raw.state);
12
+ }
13
+ }
14
+ //# sourceMappingURL=command-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-handler.js","sourceRoot":"","sources":["../src/command-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAE/D,MAAM,UAAU,kBAAkB,CAAC,GAAY;IAC7C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC;QAAE,OAAO;IAEjC,IAAI,GAAG,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAC/B,yBAAyB,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAC/D,OAAO;IACT,CAAC;IAED,IAAI,GAAG,CAAC,OAAO,KAAK,eAAe,EAAE,CAAC;QACpC,yBAAyB,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IACrE,CAAC;AACH,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { PrismTransportError } from './transport';
2
+ export interface PrismLocalConfigOptions {
3
+ port?: number;
4
+ network?: boolean;
5
+ logs?: boolean;
6
+ forceEnable?: boolean;
7
+ onConnect?: () => void;
8
+ onDisconnect?: () => void;
9
+ onError?: (error: PrismTransportError) => void;
10
+ }
11
+ /** Build SDK config for a host (defaults to port 8080). */
12
+ export declare function createPrismLocalConfig(host: string, overrides?: PrismLocalConfigOptions): {
13
+ host: string;
14
+ port: number;
15
+ network: boolean | undefined;
16
+ logs: boolean | undefined;
17
+ forceEnable: boolean | undefined;
18
+ onConnect: (() => void) | undefined;
19
+ onDisconnect: (() => void) | undefined;
20
+ onError: ((error: PrismTransportError) => void) | undefined;
21
+ };
22
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;CAChD;AAED,2DAA2D;AAC3D,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,uBAAuB;;;;;;sBARjB,IAAI;yBACD,IAAI;sBACP,mBAAmB,KAAK,IAAI;EAkB/C"}
package/dist/config.js ADDED
@@ -0,0 +1,15 @@
1
+ import { PRISM_DEFAULT_PORT } from '@sudo-ping-pong/prism-protocol';
2
+ /** Build SDK config for a host (defaults to port 8080). */
3
+ export function createPrismLocalConfig(host, overrides) {
4
+ return {
5
+ host,
6
+ port: overrides?.port ?? PRISM_DEFAULT_PORT,
7
+ network: overrides?.network,
8
+ logs: overrides?.logs,
9
+ forceEnable: overrides?.forceEnable,
10
+ onConnect: overrides?.onConnect,
11
+ onDisconnect: overrides?.onDisconnect,
12
+ onError: overrides?.onError,
13
+ };
14
+ }
15
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAapE,2DAA2D;AAC3D,MAAM,UAAU,sBAAsB,CACpC,IAAY,EACZ,SAAmC;IAEnC,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,kBAAkB;QAC3C,OAAO,EAAE,SAAS,EAAE,OAAO;QAC3B,IAAI,EAAE,SAAS,EAAE,IAAI;QACrB,WAAW,EAAE,SAAS,EAAE,WAAW;QACnC,SAAS,EAAE,SAAS,EAAE,SAAS;QAC/B,YAAY,EAAE,SAAS,EAAE,YAAY;QACrC,OAAO,EAAE,SAAS,EAAE,OAAO;KAC5B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { PrismTransport } from './transport';
2
+ import type { PrismTransportError } from './transport';
3
+ export interface PrismConfig {
4
+ /** Machine running Prism (LAN IP or localhost) */
5
+ host: string;
6
+ /** WebSocket port (default 8080) */
7
+ port?: number;
8
+ /** Intercept fetch (default true) */
9
+ network?: boolean;
10
+ /** Intercept console.log/warn/error (default true) */
11
+ logs?: boolean;
12
+ /** Force enable in production (default: only __DEV__) */
13
+ forceEnable?: boolean;
14
+ onConnect?: () => void;
15
+ onDisconnect?: () => void;
16
+ onError?: (error: PrismTransportError) => void;
17
+ }
18
+ export declare function initPrism(config: PrismConfig): void;
19
+ /** One-liner init — pass your machine's LAN IP (or Expo dev host). */
20
+ export declare function initPrismLocal(host: string, overrides?: Partial<PrismConfig>): void;
21
+ /** Reconnect with updated host/port without reinstalling patches. */
22
+ export declare function reconnectPrism(config: PrismConfig): void;
23
+ export declare function destroyPrism(): void;
24
+ export declare function getPrismTransport(): PrismTransport | null;
25
+ export { PrismTransport } from './transport';
26
+ export type { TransportOptions, PrismTransportError } from './transport';
27
+ export { prismZustandMiddleware } from './middleware/zustand';
28
+ export type { PrismZustandOptions } from './middleware/zustand';
29
+ export { PrismProfiler } from './profiler';
30
+ export type { PrismProfilerProps } from './profiler';
31
+ export { prismReduxMiddleware, withPrismStateReplay, registerPrismReduxStore, PRISM_REPLACE_STATE, } from './middleware/redux';
32
+ export type { PrismReduxOptions, PrismReplaceStateAction } from './middleware/redux';
33
+ export { parsePrismConnectUri } from '@sudo-ping-pong/prism-protocol';
34
+ export type { PrismConnectConfig, PrismCommand, StateSource } from '@sudo-ping-pong/prism-protocol';
35
+ export { installAxiosPatch } from './patches/axios';
36
+ export { createPrismLocalConfig } from './config';
37
+ export type { PrismLocalConfigOptions } from './config';
38
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAO7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,MAAM,WAAW,WAAW;IAC1B,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,yDAAyD;IACzD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;CAChD;AA+CD,wBAAgB,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAYnD;AAED,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAEnF;AAED,qEAAqE;AACrE,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAcxD;AAED,wBAAgB,YAAY,IAAI,IAAI,CASnC;AAED,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,IAAI,CAEzD;AAED,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,YAAY,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AACpG,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAClD,YAAY,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,103 @@
1
+ import { PrismTransport } from './transport';
2
+ import { installFetchPatch } from './patches/fetch';
3
+ import { installXhrPatch } from './patches/xhr';
4
+ import { installAxiosPatch } from './patches/axios';
5
+ import { installConsolePatch } from './patches/console';
6
+ import { setActiveTransport } from './transport-registry';
7
+ import { createPrismLocalConfig } from './config';
8
+ let initialized = false;
9
+ let transport = null;
10
+ let patchesInstalled = false;
11
+ let unsubs = [];
12
+ function startTransport(config) {
13
+ transport?.disconnect();
14
+ transport = new PrismTransport({
15
+ host: config.host,
16
+ port: config.port ?? 8080,
17
+ onConnect: config.onConnect ?? (() => logDev('[Prism] Connected to DevTools')),
18
+ onDisconnect: config.onDisconnect ?? (() => logDev('[Prism] Disconnected — retrying…')),
19
+ onError: config.onError ??
20
+ ((error) => {
21
+ if (error.type === 'auth') {
22
+ console.warn(`[Prism] ${error.message}`);
23
+ }
24
+ else if (error.type === 'network') {
25
+ logDev(`[Prism] ${error.message}`);
26
+ }
27
+ else {
28
+ console.warn(`[Prism] ${error.message}`);
29
+ }
30
+ }),
31
+ });
32
+ setActiveTransport(transport);
33
+ transport.resetAuthFailure();
34
+ transport.connect();
35
+ }
36
+ function installPatches(config) {
37
+ if (patchesInstalled || !transport)
38
+ return;
39
+ if (config.network !== false) {
40
+ unsubs.push(installFetchPatch());
41
+ unsubs.push(installXhrPatch());
42
+ unsubs.push(installAxiosPatch());
43
+ }
44
+ if (config.logs !== false) {
45
+ unsubs.push(installConsolePatch());
46
+ }
47
+ patchesInstalled = true;
48
+ }
49
+ export function initPrism(config) {
50
+ const isDev = typeof __DEV__ !== 'undefined'
51
+ ? __DEV__
52
+ : typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production';
53
+ if (!config.forceEnable && !isDev)
54
+ return;
55
+ if (initialized)
56
+ return;
57
+ initialized = true;
58
+ startTransport(config);
59
+ installPatches(config);
60
+ }
61
+ /** One-liner init — pass your machine's LAN IP (or Expo dev host). */
62
+ export function initPrismLocal(host, overrides) {
63
+ initPrism(createPrismLocalConfig(host, overrides));
64
+ }
65
+ /** Reconnect with updated host/port without reinstalling patches. */
66
+ export function reconnectPrism(config) {
67
+ const isDev = typeof __DEV__ !== 'undefined'
68
+ ? __DEV__
69
+ : typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production';
70
+ if (!config.forceEnable && !isDev)
71
+ return;
72
+ if (!initialized) {
73
+ initPrism(config);
74
+ return;
75
+ }
76
+ startTransport(config);
77
+ }
78
+ export function destroyPrism() {
79
+ transport?.disconnect();
80
+ setActiveTransport(null);
81
+ transport = null;
82
+ initialized = false;
83
+ for (const unsub of unsubs)
84
+ unsub();
85
+ unsubs = [];
86
+ patchesInstalled = false;
87
+ }
88
+ export function getPrismTransport() {
89
+ return transport;
90
+ }
91
+ export { PrismTransport } from './transport';
92
+ export { prismZustandMiddleware } from './middleware/zustand';
93
+ export { PrismProfiler } from './profiler';
94
+ export { prismReduxMiddleware, withPrismStateReplay, registerPrismReduxStore, PRISM_REPLACE_STATE, } from './middleware/redux';
95
+ export { parsePrismConnectUri } from '@sudo-ping-pong/prism-protocol';
96
+ export { installAxiosPatch } from './patches/axios';
97
+ export { createPrismLocalConfig } from './config';
98
+ function logDev(message) {
99
+ if (typeof __DEV__ !== 'undefined' ? __DEV__ : true) {
100
+ console.log(message);
101
+ }
102
+ }
103
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { Store, Action, Reducer } from 'redux';
2
+ /** Dispatched by Prism to replace the entire Redux state (time-travel jump). */
3
+ export declare const PRISM_REPLACE_STATE = "@@prism/REPLACE_STATE";
4
+ export interface PrismReplaceStateAction<S = unknown> extends Action<typeof PRISM_REPLACE_STATE> {
5
+ payload: S;
6
+ }
7
+ export interface PrismReduxOptions {
8
+ storeId?: string;
9
+ /** Redux action types to skip, e.g. ['@@INIT'] */
10
+ ignoredActions?: string[];
11
+ }
12
+ export declare function registerPrismReduxStore(store: Store, storeId?: string): () => void;
13
+ export declare function getPrismReduxStore(storeId: string): Store | undefined;
14
+ /**
15
+ * Wrap a root reducer so Prism can jump to a historical state snapshot.
16
+ *
17
+ * ```ts
18
+ * const store = configureStore({
19
+ * reducer: withPrismStateReplay(rootReducer),
20
+ * middleware: (gDM) => gDM().concat(prismReduxMiddleware('app')),
21
+ * });
22
+ * registerPrismReduxStore(store, 'app');
23
+ * ```
24
+ */
25
+ export declare function withPrismStateReplay<S>(reducer: Reducer<S>): Reducer<S>;
26
+ export declare function prismReduxMiddleware(storeIdOrOptions?: string | PrismReduxOptions): import('redux').Middleware;
27
+ export declare function dispatchPrismReduxCommand(storeId: string, command: 'dispatch' | 'replace_state', data: unknown): boolean;
28
+ //# sourceMappingURL=redux.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redux.d.ts","sourceRoot":"","sources":["../../src/middleware/redux.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAIpD,gFAAgF;AAChF,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAE3D,MAAM,WAAW,uBAAuB,CAAC,CAAC,GAAG,OAAO,CAAE,SAAQ,MAAM,CAAC,OAAO,mBAAmB,CAAC;IAC9F,OAAO,EAAE,CAAC,CAAC;CACZ;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAID,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,SAAU,GAAG,MAAM,IAAI,CAGnF;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAErE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAOvE;AAID,wBAAgB,oBAAoB,CAClC,gBAAgB,CAAC,EAAE,MAAM,GAAG,iBAAiB,GAC5C,OAAO,OAAO,EAAE,UAAU,CAmC5B;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,UAAU,GAAG,eAAe,EACrC,IAAI,EAAE,OAAO,GACZ,OAAO,CAcT"}
@@ -0,0 +1,94 @@
1
+ import { captureStateEvent } from '../capture';
2
+ /** Dispatched by Prism to replace the entire Redux state (time-travel jump). */
3
+ export const PRISM_REPLACE_STATE = '@@prism/REPLACE_STATE';
4
+ const reduxStores = new Map();
5
+ export function registerPrismReduxStore(store, storeId = 'redux') {
6
+ reduxStores.set(storeId, store);
7
+ return () => reduxStores.delete(storeId);
8
+ }
9
+ export function getPrismReduxStore(storeId) {
10
+ return reduxStores.get(storeId);
11
+ }
12
+ /**
13
+ * Wrap a root reducer so Prism can jump to a historical state snapshot.
14
+ *
15
+ * ```ts
16
+ * const store = configureStore({
17
+ * reducer: withPrismStateReplay(rootReducer),
18
+ * middleware: (gDM) => gDM().concat(prismReduxMiddleware('app')),
19
+ * });
20
+ * registerPrismReduxStore(store, 'app');
21
+ * ```
22
+ */
23
+ export function withPrismStateReplay(reducer) {
24
+ return (state, action) => {
25
+ if (action.type === PRISM_REPLACE_STATE) {
26
+ return action.payload;
27
+ }
28
+ return reducer(state, action);
29
+ };
30
+ }
31
+ const DEFAULT_IGNORED = ['@@INIT', '@@redux/INIT'];
32
+ export function prismReduxMiddleware(storeIdOrOptions) {
33
+ const opts = typeof storeIdOrOptions === 'string'
34
+ ? { storeId: storeIdOrOptions }
35
+ : { storeId: 'redux', ...storeIdOrOptions };
36
+ const storeId = opts.storeId ?? 'redux';
37
+ const ignored = new Set([...DEFAULT_IGNORED, ...(opts.ignoredActions ?? [])]);
38
+ return (storeApi) => {
39
+ reduxStores.set(storeId, storeApi);
40
+ return (next) => (action) => {
41
+ const prevState = storeApi.getState();
42
+ const result = next(action);
43
+ const nextState = storeApi.getState();
44
+ const actionType = action.type ?? 'unknown';
45
+ if (ignored.has(actionType) || actionType === PRISM_REPLACE_STATE) {
46
+ return result;
47
+ }
48
+ const payload = {
49
+ actionLabel: actionType,
50
+ payload: serializeAction(action),
51
+ prevState: cloneState(prevState),
52
+ nextState: cloneState(nextState),
53
+ storeId,
54
+ source: 'redux',
55
+ };
56
+ captureStateEvent(payload);
57
+ return result;
58
+ };
59
+ };
60
+ }
61
+ export function dispatchPrismReduxCommand(storeId, command, data) {
62
+ const store = reduxStores.get(storeId);
63
+ if (!store)
64
+ return false;
65
+ if (command === 'dispatch') {
66
+ store.dispatch(data);
67
+ return true;
68
+ }
69
+ store.dispatch({
70
+ type: PRISM_REPLACE_STATE,
71
+ payload: data,
72
+ });
73
+ return true;
74
+ }
75
+ function serializeAction(action) {
76
+ if (typeof action !== 'object' || action === null)
77
+ return action;
78
+ try {
79
+ JSON.stringify(action);
80
+ return action;
81
+ }
82
+ catch {
83
+ return { type: action.type, note: '(non-serializable action)' };
84
+ }
85
+ }
86
+ function cloneState(value) {
87
+ try {
88
+ return JSON.parse(JSON.stringify(value));
89
+ }
90
+ catch {
91
+ return value;
92
+ }
93
+ }
94
+ //# sourceMappingURL=redux.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redux.js","sourceRoot":"","sources":["../../src/middleware/redux.ts"],"names":[],"mappings":"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"}