@@ -12,25 +12,20 @@ import { editor } from "monaco-editor";
12
12
import { ApplyOverlay , CalculateOverlay , GetInfo } from "./bridge" ;
13
13
import { Alert } from "@speakeasy-api/moonshine" ;
14
14
import { blankOverlay , petstore } from "./defaults" ;
15
- import { useAtom } from "jotai" ;
16
15
import speakeasyWhiteLogo from "./assets/speakeasy-white.svg" ;
17
16
import openapiLogo from "./assets/openapi.svg" ;
18
- import { atom } from "jotai" ;
19
17
import { compress , decompress } from "@/compress" ;
20
18
import { CopyButton } from "@/components/CopyButton" ;
21
19
import { Button } from "@/components/ui/button" ;
22
20
import {
23
- PanelGroup ,
21
+ ImperativePanelGroupHandle ,
24
22
Panel ,
23
+ PanelGroup ,
25
24
PanelResizeHandle ,
26
- ImperativePanelGroupHandle ,
27
25
} from "react-resizable-panels" ;
28
26
import posthog from "posthog-js" ;
29
27
import { useDebounceCallback , useMediaQuery } from "usehooks-ts" ;
30
28
31
- const originalOpenAPI = atom ( petstore ) ;
32
- const changedOpenAPI = atom < string > ( "" ) ;
33
- const overlay = atom ( blankOverlay ) ;
34
29
const Link = ( { children, href } : { children : ReactNode ; href : string } ) => (
35
30
< a
36
31
className = "border-b border-transparent pb-[2px] transition-all duration-200 hover:border-current "
@@ -46,10 +41,10 @@ const Link = ({ children, href }: { children: ReactNode; href: string }) => (
46
41
function Playground ( ) {
47
42
const [ ready , setReady ] = useState ( false ) ;
48
43
49
- const [ original , setOriginal ] = useAtom ( originalOpenAPI ) ;
50
- const [ changed , setChanged ] = useAtom ( changedOpenAPI ) ;
44
+ const original = useRef ( petstore ) ;
45
+ const changed = useRef ( "" ) ;
51
46
const [ changedLoading , setChangedLoading ] = useState ( false ) ;
52
- const [ result , setResult ] = useAtom ( overlay ) ;
47
+ const result = useRef ( blankOverlay ) ;
53
48
const [ resultLoading , setResultLoading ] = useState ( false ) ;
54
49
const [ error , setError ] = useState ( "" ) ;
55
50
const [ shareUrl , setShareUrl ] = useState ( "" ) ;
@@ -66,8 +61,12 @@ function Playground() {
66
61
const getShareUrl = useCallback ( async ( ) => {
67
62
try {
68
63
setShareUrlLoading ( true ) ;
69
- const info = await GetInfo ( original , false ) ;
70
- const start = JSON . stringify ( { result, original, info } ) ;
64
+ const info = await GetInfo ( original . current , false ) ;
65
+ const start = JSON . stringify ( {
66
+ result : result . current ,
67
+ original : original . current ,
68
+ info : info ,
69
+ } ) ;
71
70
const blob = await compress ( start ) ;
72
71
73
72
const response = await fetch ( "/api/share" , {
@@ -114,24 +113,33 @@ function Playground() {
114
113
throw new Error ( "No body" ) ;
115
114
}
116
115
const decompressedData = await decompress ( blob . body ) ;
117
- const { result, original } = JSON . parse ( decompressedData ) ;
116
+ const decompressed : { original : string ; result : string } =
117
+ JSON . parse ( decompressedData ) ;
118
118
119
- setOriginal ( original ) ;
120
- setResult ( result ) ;
119
+ original . current = decompressed . original ;
120
+ result . current = decompressed . result ;
121
121
122
- const changed = await ApplyOverlay ( original , result , false ) ;
123
- const info = await GetInfo ( original , false ) ;
122
+ const changedNew = await ApplyOverlay (
123
+ original . current ,
124
+ result . current ,
125
+ false ,
126
+ ) ;
127
+ const info = await GetInfo ( original . current , false ) ;
124
128
posthog . capture ( "overlay.speakeasy.com:load-shared" , {
125
129
openapi : JSON . parse ( info ) ,
126
130
} ) ;
127
131
128
- setChanged ( changed ) ;
132
+ changed . current = changedNew ;
129
133
} catch ( error : any ) {
130
134
console . error ( "invalid share url:" , error . message ) ;
131
135
}
132
136
} else {
133
- const changed = await ApplyOverlay ( original , result , false ) ;
134
- setChanged ( changed ) ;
137
+ const changedNew = await ApplyOverlay (
138
+ original . current ,
139
+ result . current ,
140
+ false ,
141
+ ) ;
142
+ changed . current = changedNew ;
135
143
}
136
144
setReady ( true ) ;
137
145
} ) ( ) ;
@@ -141,9 +149,14 @@ function Playground() {
141
149
async ( value : string | undefined , _ : editor . IModelContentChangedEvent ) => {
142
150
try {
143
151
setResultLoading ( true ) ;
144
- setOriginal ( value || "" ) ;
145
- const res = await CalculateOverlay ( value || "" , changed , true ) ;
146
- setResult ( res ) ;
152
+ original . current = value || "" ;
153
+ const res = await CalculateOverlay (
154
+ value || "" ,
155
+ changed . current ,
156
+ result . current ,
157
+ true ,
158
+ ) ;
159
+ result . current = res ;
147
160
setError ( "" ) ;
148
161
} catch ( e : unknown ) {
149
162
if ( e instanceof Error ) {
@@ -153,7 +166,7 @@ function Playground() {
153
166
setResultLoading ( false ) ;
154
167
}
155
168
} ,
156
- [ changed , original ] ,
169
+ [ ] ,
157
170
) ;
158
171
159
172
const onChangeADebounced = useDebounceCallback ( onChangeA , 500 ) ;
@@ -162,9 +175,13 @@ function Playground() {
162
175
async ( value : string | undefined , _ : editor . IModelContentChangedEvent ) => {
163
176
try {
164
177
setResultLoading ( true ) ;
165
- setChanged ( value || "" ) ;
166
- const res = await CalculateOverlay ( original , value || "" , true ) ;
167
- setResult ( res ) ;
178
+ changed . current = value || "" ;
179
+ result . current = await CalculateOverlay (
180
+ original . current ,
181
+ value || "" ,
182
+ result . current ,
183
+ true ,
184
+ ) ;
168
185
setError ( "" ) ;
169
186
} catch ( e : unknown ) {
170
187
if ( e instanceof Error ) {
@@ -174,7 +191,7 @@ function Playground() {
174
191
setResultLoading ( false ) ;
175
192
}
176
193
} ,
177
- [ changed , original ] ,
194
+ [ ] ,
178
195
) ;
179
196
180
197
const onChangeBDebounced = useDebounceCallback ( onChangeB , 500 ) ;
@@ -183,9 +200,12 @@ function Playground() {
183
200
async ( value : string | undefined , _ : editor . IModelContentChangedEvent ) => {
184
201
try {
185
202
setChangedLoading ( true ) ;
186
- setResult ( value || "" ) ;
187
- const res = await ApplyOverlay ( original , value || "" , true ) ;
188
- setChanged ( res ) ;
203
+ result . current = value || "" ;
204
+ changed . current = await ApplyOverlay (
205
+ original . current ,
206
+ value || "" ,
207
+ true ,
208
+ ) ;
189
209
setError ( "" ) ;
190
210
} catch ( e : unknown ) {
191
211
if ( e instanceof Error ) {
@@ -195,15 +215,15 @@ function Playground() {
195
215
setChangedLoading ( false ) ;
196
216
}
197
217
} ,
198
- [ changed , original ] ,
218
+ [ ] ,
199
219
) ;
200
220
201
221
const onChangeCDebounced = useDebounceCallback ( onChangeC , 500 ) ;
202
222
203
223
useEffect ( ( ) => {
204
224
const tryHandlePageTitle = async ( ) => {
205
225
try {
206
- const info = await GetInfo ( original ) ;
226
+ const info = await GetInfo ( original . current ) ;
207
227
const { title, version } = JSON . parse ( info ) ;
208
228
const pageTitle = `${ title } ${ version } | Speakeasy OpenAPI Overlay Playground` ;
209
229
if ( document . title !== pageTitle ) {
@@ -312,7 +332,7 @@ function Playground() {
312
332
onClick = { getShareUrl }
313
333
disabled = { shareUrlLoading }
314
334
>
315
- Short URL
335
+ Share
316
336
</ Button >
317
337
< div className = "flex items-center gap-x-2 grow" >
318
338
{ shareUrl ? < CopyButton value = { shareUrl } /> : null }
@@ -354,7 +374,7 @@ function Playground() {
354
374
< div style = { { height : "calc(100vh - 50px)" } } >
355
375
< Editor
356
376
readonly = { false }
357
- value = { original }
377
+ value = { original . current }
358
378
onChange = { onChangeADebounced }
359
379
title = "Original"
360
380
index = { 0 }
@@ -367,8 +387,8 @@ function Playground() {
367
387
< div style = { { height : "calc(100vh - 50px)" } } >
368
388
< Editor
369
389
readonly = { false }
370
- original = { original }
371
- value = { changed }
390
+ original = { original . current }
391
+ value = { changed . current }
372
392
onChange = { onChangeBDebounced }
373
393
loading = { changedLoading }
374
394
title = { "Original + Overlay" }
@@ -382,7 +402,7 @@ function Playground() {
382
402
< div style = { { height : "calc(100vh - 50px)" } } >
383
403
< Editor
384
404
readonly = { false }
385
- value = { result }
405
+ value = { result . current }
386
406
onChange = { onChangeCDebounced }
387
407
loading = { resultLoading }
388
408
title = { "Overlay" }
0 commit comments