Skip to content

Commit c147504

Browse files
committed
fix: bug where circulars are not processed properly
1 parent 57034db commit c147504

File tree

6 files changed

+35
-5
lines changed

6 files changed

+35
-5
lines changed

examples/with-nextjs-api/src/app/api/user/route.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { NextResponse } from 'next/server'
22
import { faker } from '@faker-js/faker'
3-
import { capture } from 'useflytrap'
3+
import { capture, identify } from 'useflytrap'
44

55
// @ts-expect-error
66
const mockUsers = [...Array(100).keys()].map((i) => ({
@@ -26,6 +26,7 @@ function listUsers(options: ListUsersOptions = { per_page: 50, page: 0 }) {
2626
export async function GET(request: Request) {
2727
const { searchParams } = new URL(request.url)
2828
const userId = searchParams.get('userId')
29+
if (userId) identify(userId)
2930

3031
/**
3132
* Here we're making an oversight, we should include `{ per_page: 100, page: 0 }` to include

examples/with-nextjs-api/src/app/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export default function Home() {
5858
/>
5959
</div>
6060

61-
<input value={username} onChange={(e) => setUsername(e.target.value)} placeholder="Username" />
61+
<input value={username} onChange={(e) => setUsername(e.target.value)} placeholder="Username" style={{ color: 'black' }} />
6262
<button onClick={fetchDetails}>Fetch account details</button>
6363
{error && (
6464
<div className='space-y-2'>

src/core/storage.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,25 @@ export const liveFlytrapStorage: FlytrapStorage = {
198198
calls = processCaptures(calls)
199199
functions = processCaptures(functions)
200200

201-
calls = removeCircularDependencies(calls)
202-
functions = removeCircularDependencies(functions)
201+
// Remove the circular from `calls` and `functions`
202+
for (let i = 0; i < calls.length; i++) {
203+
for (let j = 0; j < calls[i].invocations.length; j++) {
204+
calls[i].invocations[j].args = calls[i].invocations[j].args.map((a) =>
205+
removeCircularDependencies(a)
206+
)
207+
calls[i].invocations[j].output = removeCircularDependencies(calls[i].invocations[j].output)
208+
}
209+
}
210+
for (let i = 0; i < functions.length; i++) {
211+
for (let j = 0; j < functions[i].invocations.length; j++) {
212+
functions[i].invocations[j].args = functions[i].invocations[j].args.map((a) =>
213+
removeCircularDependencies(a)
214+
)
215+
functions[i].invocations[j].output = removeCircularDependencies(
216+
functions[i].invocations[j].output
217+
)
218+
}
219+
}
203220

204221
const args = [...extractArgs(calls), ...extractArgs(functions)]
205222
const outputs = [...extractOutputs(calls), ...extractOutputs(functions)]

src/core/stringify.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ export function stringify(obj: any): string {
110110
if (key.startsWith('_')) return // Don't compare React's internal props.
111111
if (typeof value === 'object' && value !== null) {
112112
if (seen.has(value)) return FLYTRAP_CIRCULAR
113+
// if (seen.has(value)) return null
113114
seen.add(value)
114115
}
115116
return value

src/transform.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ export const unpluginOptions: UnpluginOptions = {
189189
}).toString()
190190
}
191191

192-
if (!config.disableArtifacts) {
192+
if (!config.disableArtifacts && process?.env?.NODE_ENV === 'production') {
193193
// Push artifacts
194194
log.info(
195195
'storage',

test/regression.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { describe, expect, it } from 'vitest'
33
import { extractArtifacts } from '../src/transform/artifacts/artifacts'
44
import { initTRPC } from '@trpc/server'
55
import { removeCircularDependencies } from '../src/core/stringify'
6+
import SuperJSON from 'superjson'
67

78
describe('Regression', () => {
89
it('regression #1 > generates correct artifacts that match the transformed code', async () => {
@@ -39,4 +40,14 @@ describe('Regression', () => {
3940
const withoutCirculars = removeCircularDependencies(trpcInstance)
4041
expect(typeof withoutCirculars).toEqual('object')
4142
})
43+
44+
it.skip("regression #3 > doesn't give false positives to circular", () => {
45+
const items = ['abc', 'def']
46+
const calls = [items, items]
47+
const callsWithoutCirculars = removeCircularDependencies(calls)
48+
expect(callsWithoutCirculars).toEqual([
49+
['abc', 'def'],
50+
['abc', 'def']
51+
])
52+
})
4253
})

0 commit comments

Comments
 (0)