@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.
- package/LICENSE +21 -0
- package/README.md +182 -0
- package/dist/buffer.d.ts +8 -0
- package/dist/buffer.d.ts.map +1 -0
- package/dist/buffer.js +19 -0
- package/dist/buffer.js.map +1 -0
- package/dist/capture.d.ts +5 -0
- package/dist/capture.d.ts.map +1 -0
- package/dist/capture.js +36 -0
- package/dist/capture.js.map +1 -0
- package/dist/command-handler.d.ts +2 -0
- package/dist/command-handler.d.ts.map +1 -0
- package/dist/command-handler.js +14 -0
- package/dist/command-handler.js.map +1 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +15 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +103 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/redux.d.ts +28 -0
- package/dist/middleware/redux.d.ts.map +1 -0
- package/dist/middleware/redux.js +94 -0
- package/dist/middleware/redux.js.map +1 -0
- package/dist/middleware/zustand.d.ts +11 -0
- package/dist/middleware/zustand.d.ts.map +1 -0
- package/dist/middleware/zustand.js +37 -0
- package/dist/middleware/zustand.js.map +1 -0
- package/dist/patches/axios.d.ts +4 -0
- package/dist/patches/axios.d.ts.map +1 -0
- package/dist/patches/axios.js +140 -0
- package/dist/patches/axios.js.map +1 -0
- package/dist/patches/capture-guard.d.ts +5 -0
- package/dist/patches/capture-guard.d.ts.map +1 -0
- package/dist/patches/capture-guard.js +24 -0
- package/dist/patches/capture-guard.js.map +1 -0
- package/dist/patches/console.d.ts +2 -0
- package/dist/patches/console.d.ts.map +1 -0
- package/dist/patches/console.js +21 -0
- package/dist/patches/console.js.map +1 -0
- package/dist/patches/fetch.d.ts +4 -0
- package/dist/patches/fetch.d.ts.map +1 -0
- package/dist/patches/fetch.js +106 -0
- package/dist/patches/fetch.js.map +1 -0
- package/dist/patches/xhr.d.ts +2 -0
- package/dist/patches/xhr.d.ts.map +1 -0
- package/dist/patches/xhr.js +74 -0
- package/dist/patches/xhr.js.map +1 -0
- package/dist/profiler.d.ts +9 -0
- package/dist/profiler.d.ts.map +1 -0
- package/dist/profiler.js +19 -0
- package/dist/profiler.js.map +1 -0
- package/dist/transport-registry.d.ts +8 -0
- package/dist/transport-registry.d.ts.map +1 -0
- package/dist/transport-registry.js +11 -0
- package/dist/transport-registry.js.map +1 -0
- package/dist/transport.d.ts +38 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +153 -0
- package/dist/transport.js.map +1 -0
- package/package.json +111 -0
- package/src/buffer.ts +23 -0
- package/src/capture.ts +40 -0
- package/src/command-handler.ts +15 -0
- package/src/config.ts +29 -0
- package/src/env.d.ts +1 -0
- package/src/index.ts +148 -0
- package/src/middleware/redux.ts +126 -0
- package/src/middleware/zustand.ts +58 -0
- package/src/patches/axios.ts +182 -0
- package/src/patches/capture-guard.ts +24 -0
- package/src/patches/console.ts +27 -0
- package/src/patches/fetch.ts +118 -0
- package/src/patches/xhr.ts +103 -0
- package/src/profiler.tsx +36 -0
- package/src/transport-registry.ts +20 -0
- 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
|
package/dist/buffer.d.ts
ADDED
|
@@ -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"}
|
package/dist/capture.js
ADDED
|
@@ -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 @@
|
|
|
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"}
|
package/dist/config.d.ts
ADDED
|
@@ -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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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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"}
|