fix(perf): log less frequently (#34387)

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Paul D'Ambra
2025-07-01 15:11:58 +01:00
committed by GitHub
parent 21476104f7
commit fb42a9c38b
6 changed files with 350 additions and 130 deletions

View File

@@ -85,9 +85,9 @@
"@posthog/products-surveys": "workspace:*",
"@posthog/products-user-interviews": "workspace:*",
"@posthog/products-web-analytics": "workspace:*",
"@posthog/rrweb": "0.0.21",
"@posthog/rrweb-plugin-console-record": "0.0.21",
"@posthog/rrweb-types": "0.0.21",
"@posthog/rrweb": "0.0.22",
"@posthog/rrweb-plugin-console-record": "0.0.22",
"@posthog/rrweb-types": "0.0.22",
"@posthog/tailwind": "workspace:*",
"@radix-ui/react-accordion": "^1.2.2",
"@radix-ui/react-context-menu": "^2.2.6",

View File

@@ -66,8 +66,6 @@ const waitForDataLogic = async (playerKey: string): Promise<BuiltLogic<sessionRe
})
if (dataLogic !== null) {
// eslint-disable-next-line no-console
console.log('found after retries', retries)
return dataLogic
}

View File

@@ -167,6 +167,77 @@ const defaultStyleRules = `.ph-no-capture { background-image: ${PLACEHOLDER_SVG_
const shopifyShorthandCSSFix =
'@media (prefers-reduced-motion: no-preference) { .scroll-trigger:not(.scroll-trigger--offscreen).animate--slide-in { animation: var(--animation-slide-in) } }'
export type LogType = 'log' | 'warning'
export type LoggingTimers = Record<LogType, NodeJS.Timeout | null>
export type BuiltLogging = {
logger: playerConfig['logger']
timers: LoggingTimers
}
export const makeNoOpLogger = (): BuiltLogging => {
return {
logger: {
log: () => {},
warn: () => {},
},
timers: { log: null, warning: null },
}
}
export const makeLogger = (onIncrement: (count: number) => void): BuiltLogging => {
const counters = {
log: 0,
warning: 0,
}
;(window as any)[`__posthog_player_logs`] = (window as any)[`__posthog_player_logs`] || []
;(window as any)[`__posthog_player_warnings`] = (window as any)[`__posthog_player_warnings`] || []
const logStores: Record<LogType, any[]> = {
log: (window as any)[`__posthog_player_logs`],
warning: (window as any)[`__posthog_player_warnings`],
}
const timers: LoggingTimers = {
log: null,
warning: null,
}
const logger = (type: LogType): ((message?: any, ...optionalParams: any[]) => void) => {
// NOTE: RRWeb can log _alot_ of warnings,
// so we debounce the count otherwise we just end up making the performance worse
// We also don't log the messages directly.
// Sometimes the sheer size of messages and warnings can cause the browser to crash deserializing it all
return (...args: any[]): void => {
logStores[type].push(args)
counters[type] += 1
if (!timers[type]) {
timers[type] = setTimeout(() => {
timers[type] = null
if (type === 'warning') {
onIncrement(logStores[type].length)
}
console.warn(
`[PostHog Replayer] ${counters[type]} ${type}s (window.__posthog_player_${type}s to safely log them)`
)
counters[type] = 0
}, 5000)
}
}
}
return {
logger: {
log: logger('log'),
warn: logger('warning'),
},
timers,
}
}
export const COMMON_REPLAYER_CONFIG: Partial<playerConfig> = {
triggerFocus: false,
insertStyleRules: [defaultStyleRules, shopifyShorthandCSSFix],

View File

@@ -17,6 +17,7 @@ import { useMocks } from '~/mocks/jest'
import { initKeaTests } from '~/test/init'
import { sessionRecordingEventUsageLogic } from '../sessionRecordingEventUsageLogic'
import { makeLogger } from 'scenes/session-recordings/player/rrweb'
describe('sessionRecordingPlayerLogic', () => {
let logic: ReturnType<typeof sessionRecordingPlayerLogic.build>
@@ -329,32 +330,32 @@ describe('sessionRecordingPlayerLogic', () => {
}),
})
})
})
describe('the logger override', () => {
it('captures replayer warnings', async () => {
jest.useFakeTimers()
logic = sessionRecordingPlayerLogic({
sessionRecordingId: '4',
playerKey: 'test',
matchingEventsMatchType: {
matchType: 'uuid',
eventUUIDs: listOfMatchingEvents.map((event) => event.uuid),
},
})
logic.mount()
console.warn('[replayer]', 'test')
console.warn('[replayer]', 'test2')
let warningCounts = 0
const logger = makeLogger((x) => (warningCounts += x))
expect(mockWarn).not.toHaveBeenCalled()
logger.logger.warn('[replayer]', 'test')
logger.logger.warn('[replayer]', 'test2')
logger.logger.log('[replayer]', 'test3')
expect((window as any).__posthog_player_warnings).toEqual([
['[replayer]', 'test'],
['[replayer]', 'test2'],
])
expect((window as any).__posthog_player_logs).toEqual([['[replayer]', 'test3']])
jest.runOnlyPendingTimers()
expect(mockWarn).toHaveBeenCalledWith(
'[PostHog Replayer] 2 warnings (window.__posthog_player_warnings to safely log them)'
)
expect(mockWarn).toHaveBeenCalledWith(
'[PostHog Replayer] 1 logs (window.__posthog_player_logs to safely log them)'
)
})
})
})

View File

@@ -24,7 +24,6 @@ import { FEATURE_FLAGS } from 'lib/constants'
import { now } from 'lib/dayjs'
import { featureFlagLogic } from 'lib/logic/featureFlagLogic'
import { clamp, downloadFile, findLastIndex, objectsEqual, uuid } from 'lib/utils'
import { wrapConsole } from 'lib/utils/wrapConsole'
import posthog from 'posthog-js'
import { RefObject } from 'react'
import { openBillingPopupModal } from 'scenes/billing/BillingPopup'
@@ -53,7 +52,7 @@ import { sessionRecordingEventUsageLogic } from '../sessionRecordingEventUsageLo
import { playerCommentOverlayLogic } from './playerFrameCommentOverlayLogic'
import { playerCommentOverlayLogicType } from './playerFrameCommentOverlayLogicType'
import { playerSettingsLogic } from './playerSettingsLogic'
import { COMMON_REPLAYER_CONFIG, CorsPlugin, HLSPlayerPlugin } from './rrweb'
import { BuiltLogging, COMMON_REPLAYER_CONFIG, CorsPlugin, HLSPlayerPlugin, makeLogger, makeNoOpLogger } from './rrweb'
import { CanvasReplayerPlugin } from './rrweb/canvas/canvas-plugin'
import type { sessionRecordingPlayerLogicType } from './sessionRecordingPlayerLogicType'
import { deleteRecording } from './utils/playerUtils'
@@ -155,6 +154,7 @@ const ACTIVE_SOURCES = [
IncrementalSource.MediaInteraction,
IncrementalSource.Drag,
]
function isUserActivity(snapshot: eventWithTime): boolean {
return (
snapshot.type === INCREMENTAL_SNAPSHOT_EVENT_TYPE &&
@@ -882,6 +882,18 @@ export const sessionRecordingPlayerLogic = kea<sessionRecordingPlayerLogicType>(
plugins.push(CanvasReplayerPlugin(values.sessionPlayerData.snapshotsByWindowId[windowId]))
// we override the console in the player, with one which stores its data instead of logging
// there is a debounced logger hidden inside that.
// we have to cache those timers so that we can clear them in the beforeUnmount
// rrweb can log so much that it becomes a performance issue
// this overridden logging avoids some recordings freezing the browser
// outside of standard mode, we swallow the logs completely
const logging =
props.mode === SessionRecordingPlayerMode.Standard
? makeLogger(actions.incrementWarningCount)
: makeNoOpLogger()
cache.consoleDebounceTimers = logging.timers
const config: Partial<playerConfig> & { onError: (error: any) => void } = {
root: values.rootFrame,
...COMMON_REPLAYER_CONFIG,
@@ -893,6 +905,7 @@ export const sessionRecordingPlayerLogic = kea<sessionRecordingPlayerLogicType>(
onError: (error) => {
actions.playerErrorSeen(error)
},
logger: logging.logger,
}
const replayer = new Replayer(values.sessionPlayerData.snapshotsByWindowId[windowId], config)
@@ -1469,7 +1482,6 @@ export const sessionRecordingPlayerLogic = kea<sessionRecordingPlayerLogicType>(
cache.pausedMediaElements = []
values.player?.replayer?.destroy()
actions.setPlayer(null)
cache.unmountConsoleWarns?.()
const playTimeMs = values.playingTimeTracking.watchTime || 0
const summaryAnalytics: RecordingViewedSummaryAnalytics = {
@@ -1490,6 +1502,16 @@ export const sessionRecordingPlayerLogic = kea<sessionRecordingPlayerLogicType>(
playTimeMs === 0 ? 'recording viewed with no playtime summary' : 'recording viewed summary',
summaryAnalytics
)
if (cache.consoleDebounceTimers) {
Object.values(cache.consoleDebounceTimers as BuiltLogging['timers']).forEach((timer) => {
if (timer) {
clearTimeout(timer)
}
})
}
;(window as any)[`__posthog_player_logs`] = undefined
;(window as any)[`__posthog_player_warnings`] = undefined
}),
afterMount(({ props, actions, cache }) => {
@@ -1509,8 +1531,6 @@ export const sessionRecordingPlayerLogic = kea<sessionRecordingPlayerLogicType>(
}
cache.openTime = performance.now()
cache.unmountConsoleWarns = manageConsoleWarns(cache, actions.incrementWarningCount)
}),
])
@@ -1519,48 +1539,3 @@ export const getCurrentPlayerTime = (logicProps: SessionRecordingPlayerLogicProp
const playerTime = sessionRecordingPlayerLogic.findMounted(logicProps)?.values.currentPlayerTime || 0
return Math.floor(playerTime / 1000)
}
export const manageConsoleWarns = (cache: any, onIncrement: (count: number) => void): (() => void) => {
// NOTE: RRWeb can log _alot_ of warnings, so we debounce the count otherwise we just end up making the performance worse
// We also don't log the warnings directly. Sometimes the sheer size of messages and warnings can cause the browser to crash deserializing it all
;(window as any).__posthog_player_warnings = []
const warnings: any[][] = (window as any).__posthog_player_warnings
let counter = 0
let consoleWarnDebounceTimer: NodeJS.Timeout | null = null
const actualConsoleWarn = console.warn
const debouncedCounter = (args: any[]): void => {
warnings.push(args)
counter += 1
if (!consoleWarnDebounceTimer) {
consoleWarnDebounceTimer = setTimeout(() => {
consoleWarnDebounceTimer = null
onIncrement(warnings.length)
actualConsoleWarn(
`[PostHog Replayer] ${counter} warnings (window.__posthog_player_warnings to safely log them)`
)
counter = 0
}, 1000)
}
}
const resetConsoleWarn = wrapConsole('warn', (args) => {
if (typeof args[0] === 'string' && args[0].includes('[replayer]')) {
debouncedCounter(args)
// WARNING: Logging these out can cause the browser to completely crash, so we want to delay it and
return false
}
return true
})
return () => {
resetConsoleWarn()
clearTimeout(cache.consoleWarnDebounceTimer)
}
}

301
pnpm-lock.yaml generated
View File

@@ -314,7 +314,7 @@ importers:
version: 7.3.0(less@4.2.2)(webpack@5.88.2)
postcss-loader:
specifier: ^4.3.0
version: 4.3.0(postcss@8.5.4)(webpack@5.88.2)
version: 4.3.0(postcss@8.5.6)(webpack@5.88.2)
raw-loader:
specifier: ^4.0.2
version: 4.0.2(webpack@5.88.2)
@@ -605,14 +605,14 @@ importers:
specifier: workspace:*
version: link:../products/web_analytics
'@posthog/rrweb':
specifier: 0.0.21
version: 0.0.21
specifier: 0.0.22
version: 0.0.22
'@posthog/rrweb-plugin-console-record':
specifier: 0.0.21
version: 0.0.21(@posthog/rrweb-utils@0.0.4)(@posthog/rrweb@0.0.21)
specifier: 0.0.22
version: 0.0.22(@posthog/rrweb-utils@0.0.4)(@posthog/rrweb@0.0.22)
'@posthog/rrweb-types':
specifier: 0.0.21
version: 0.0.21
specifier: 0.0.22
version: 0.0.22
'@posthog/tailwind':
specifier: workspace:*
version: link:../common/tailwind
@@ -1905,7 +1905,7 @@ importers:
version: 8.57.0
jest:
specifier: '*'
version: 29.7.0(@types/node@18.18.4)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@18.18.4)(typescript@5.2.2))
version: 29.7.0(@types/node@22.15.17)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2))
kea:
specifier: '*'
version: 3.1.5(react@18.2.0)
@@ -1959,7 +1959,7 @@ importers:
version: 3.1.3
jest:
specifier: '*'
version: 29.7.0(@types/node@18.18.4)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@18.18.4)(typescript@5.2.2))
version: 29.7.0(@types/node@22.15.17)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2))
kea:
specifier: '*'
version: 3.1.5(react@18.2.0)
@@ -4994,8 +4994,8 @@ packages:
'@posthog/rrdom@0.0.4':
resolution: {integrity: sha512-hUZOgnIxzB6ZWgKBbuf79oHko+7x1+sQMVtovY0k6fO67e5SwhKkLq3Y/Tn2ayIyUqEKqL8971wP1cmIeIVO+A==}
'@posthog/rrweb-plugin-console-record@0.0.21':
resolution: {integrity: sha512-0/x6Kf1NvMn1VUJ2bp4gtNyXdMydl4xnjBnXa8tSPWaVgtOErf1rffy2r++crJ+hmKN3VI6NabPKYigaRpazwg==}
'@posthog/rrweb-plugin-console-record@0.0.22':
resolution: {integrity: sha512-Ej0mT86w2ASY4k1gdwCaoitDpGoZXouS6ZWGc3Rv36tsUy5ZyWG+ESa50oMboRO+ufHV9/cTymdxXp3q9015MA==}
peerDependencies:
'@posthog/rrweb': '*'
'@posthog/rrweb-utils': '*'
@@ -5003,8 +5003,8 @@ packages:
'@posthog/rrweb-snapshot@0.0.4':
resolution: {integrity: sha512-ifZH6T0FYjHtiCcqQOdrLn8YH9I7OOIWu2GSZMCzFd8F8oX1gtX4Tk/yX0sA6qAIWtfwDC0dKXgHWS2/EqGjgg==}
'@posthog/rrweb-types@0.0.21':
resolution: {integrity: sha512-gxnOG0A6L27fBXW/YsK01tdabgPmbaUy0dCEBe4ZxB+HProDid9HROkEFLIfiUkO0y1bW7Ua380HZLIRhvYMLw==}
'@posthog/rrweb-types@0.0.22':
resolution: {integrity: sha512-KEKOQrGsaid6W+tfv8u65MLcdkATo7haJlCqyaNPHR1c+wCpBGyF8ZzzMzhFBCiaqBm0+e/0P/nU/mRO6azgnQ==}
'@posthog/rrweb-types@0.0.8':
resolution: {integrity: sha512-CdZkKgr6VhCNJZLRdw7TC1J4iI/H+nEt5NZSBjV8vglQ4o31kl0KUfo2g0r6EvAm3mX3p5/mGrqub+LxABwzQQ==}
@@ -5012,8 +5012,8 @@ packages:
'@posthog/rrweb-utils@0.0.4':
resolution: {integrity: sha512-ndkpquzqXV/i0u4paOPiESWE/wdOEPdM+Q+sFQfcn6KnvjxtkzsnNNSlOcNHSwuRh0bCk3Cgs2ixDVTSZ+Zdtg==}
'@posthog/rrweb@0.0.21':
resolution: {integrity: sha512-Wk1m2cX2o3PymHfgXmx23IlvPuYBzxPkDatBR9I5eSsTPuDxpEQXRd49Lh3Rq91MK8lqCoSql+lBwMk9AIsjWA==}
'@posthog/rrweb@0.0.22':
resolution: {integrity: sha512-1SvlKE7Dgvo+MySEDaRln+SLGcrD8eXJMUbWUf4eRRsRRerlKETdYUbPAkW54hXY3pKpCkYxEbpiI4QveuXBPA==}
'@posthog/siphash@1.1.1':
resolution: {integrity: sha512-JUFk57H89fOnHpF62FDyFGw4uXeHAX20OPfkLL8/iqg/xrVp5Q21LvJUDijmS5wt0avgUwXF2bxYgaZ5iWRmAg==}
@@ -14081,10 +14081,6 @@ packages:
resolution: {integrity: sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==}
engines: {node: ^10 || ^12 || >=14}
postcss@8.5.4:
resolution: {integrity: sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==}
engines: {node: ^10 || ^12 || >=14}
postcss@8.5.6:
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
engines: {node: ^10 || ^12 || >=14}
@@ -19813,6 +19809,41 @@ snapshots:
- supports-color
- ts-node
'@jest/core@29.7.0(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2))':
dependencies:
'@jest/console': 29.7.0
'@jest/reporters': 29.7.0
'@jest/test-result': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
'@types/node': 18.18.4
ansi-escapes: 4.3.2
chalk: 4.1.2
ci-info: 3.8.0
exit: 0.1.2
graceful-fs: 4.2.11
jest-changed-files: 29.7.0
jest-config: 29.7.0(@types/node@18.18.4)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2))
jest-haste-map: 29.7.0
jest-message-util: 29.7.0
jest-regex-util: 29.6.3
jest-resolve: 29.7.0
jest-resolve-dependencies: 29.7.0
jest-runner: 29.7.0
jest-runtime: 29.7.0
jest-snapshot: 29.7.0
jest-util: 29.7.0
jest-validate: 29.7.0
jest-watcher: 29.7.0
micromatch: 4.0.8
pretty-format: 29.7.0
slash: 3.0.0
strip-ansi: 6.0.1
transitivePeerDependencies:
- babel-plugin-macros
- supports-color
- ts-node
'@jest/create-cache-key-function@29.7.0':
dependencies:
'@jest/types': 29.6.3
@@ -21051,26 +21082,26 @@ snapshots:
dependencies:
'@posthog/rrweb-snapshot': 0.0.4
'@posthog/rrweb-plugin-console-record@0.0.21(@posthog/rrweb-utils@0.0.4)(@posthog/rrweb@0.0.21)':
'@posthog/rrweb-plugin-console-record@0.0.22(@posthog/rrweb-utils@0.0.4)(@posthog/rrweb@0.0.22)':
dependencies:
'@posthog/rrweb': 0.0.21
'@posthog/rrweb': 0.0.22
'@posthog/rrweb-utils': 0.0.4
'@posthog/rrweb-snapshot@0.0.4':
dependencies:
postcss: 8.5.4
postcss: 8.5.6
'@posthog/rrweb-types@0.0.21': {}
'@posthog/rrweb-types@0.0.22': {}
'@posthog/rrweb-types@0.0.8': {}
'@posthog/rrweb-utils@0.0.4': {}
'@posthog/rrweb@0.0.21':
'@posthog/rrweb@0.0.22':
dependencies:
'@posthog/rrdom': 0.0.4
'@posthog/rrweb-snapshot': 0.0.4
'@posthog/rrweb-types': 0.0.21
'@posthog/rrweb-types': 0.0.22
'@posthog/rrweb-utils': 0.0.4
'@types/css-font-loading-module': 0.0.7
'@xstate/fsm': 1.6.5
@@ -23551,7 +23582,7 @@ snapshots:
commander: 9.4.1
expect-playwright: 0.8.0
glob: 10.4.5
jest: 29.7.0(@types/node@18.18.4)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@18.18.4)(typescript@5.2.2))
jest: 29.7.0
jest-circus: 29.7.0
jest-environment-node: 29.7.0
jest-junit: 16.0.0
@@ -26546,6 +26577,21 @@ snapshots:
- supports-color
- ts-node
create-jest@29.7.0(@types/node@22.15.17)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2)):
dependencies:
'@jest/types': 29.6.3
chalk: 4.1.2
exit: 0.1.2
graceful-fs: 4.2.11
jest-config: 29.7.0(@types/node@22.15.17)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2))
jest-util: 29.7.0
prompts: 2.4.2
transitivePeerDependencies:
- '@types/node'
- babel-plugin-macros
- supports-color
- ts-node
create-require@1.1.1: {}
crelt@1.0.5: {}
@@ -26627,12 +26673,12 @@ snapshots:
css-loader@6.8.1(webpack@5.88.2):
dependencies:
icss-utils: 5.1.0(postcss@8.5.4)
postcss: 8.5.4
postcss-modules-extract-imports: 3.0.0(postcss@8.5.4)
postcss-modules-local-by-default: 4.0.3(postcss@8.5.4)
postcss-modules-scope: 3.0.0(postcss@8.5.4)
postcss-modules-values: 4.0.0(postcss@8.5.4)
icss-utils: 5.1.0(postcss@8.5.6)
postcss: 8.5.6
postcss-modules-extract-imports: 3.0.0(postcss@8.5.6)
postcss-modules-local-by-default: 4.0.3(postcss@8.5.6)
postcss-modules-scope: 3.0.0(postcss@8.5.6)
postcss-modules-values: 4.0.0(postcss@8.5.6)
postcss-value-parser: 4.2.0
semver: 7.7.0
webpack: 5.88.2(@swc/core@1.11.4(@swc/helpers@0.5.15))(esbuild@0.18.20)(webpack-cli@5.1.4)
@@ -29082,9 +29128,9 @@ snapshots:
dependencies:
postcss: 7.0.39
icss-utils@5.1.0(postcss@8.5.4):
icss-utils@5.1.0(postcss@8.5.6):
dependencies:
postcss: 8.5.4
postcss: 8.5.6
idb@8.0.3: {}
@@ -29612,6 +29658,25 @@ snapshots:
- babel-plugin-macros
- supports-color
jest-cli@29.7.0:
dependencies:
'@jest/core': 29.7.0(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@18.18.4)(typescript@5.2.2))
'@jest/test-result': 29.7.0
'@jest/types': 29.6.3
chalk: 4.1.2
create-jest: 29.7.0(@types/node@22.15.17)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2))
exit: 0.1.2
import-local: 3.1.0
jest-config: 29.7.0(@types/node@22.15.17)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2))
jest-util: 29.7.0
jest-validate: 29.7.0
yargs: 17.7.1
transitivePeerDependencies:
- '@types/node'
- babel-plugin-macros
- supports-color
- ts-node
jest-cli@29.7.0(@types/node@18.18.4)(ts-node@10.9.1(@swc/core@1.10.14(@swc/helpers@0.5.15))(@types/node@18.18.4)(typescript@5.2.2)):
dependencies:
'@jest/core': 29.7.0(ts-node@10.9.1(@swc/core@1.10.14(@swc/helpers@0.5.15))(@types/node@18.18.4)(typescript@5.2.2))
@@ -29650,6 +29715,25 @@ snapshots:
- supports-color
- ts-node
jest-cli@29.7.0(@types/node@22.15.17)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2)):
dependencies:
'@jest/core': 29.7.0(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2))
'@jest/test-result': 29.7.0
'@jest/types': 29.6.3
chalk: 4.1.2
create-jest: 29.7.0(@types/node@22.15.17)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2))
exit: 0.1.2
import-local: 3.1.0
jest-config: 29.7.0(@types/node@22.15.17)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2))
jest-util: 29.7.0
jest-validate: 29.7.0
yargs: 17.7.1
transitivePeerDependencies:
- '@types/node'
- babel-plugin-macros
- supports-color
- ts-node
jest-config@29.7.0(@types/node@18.18.4)(ts-node@10.9.1(@swc/core@1.10.14(@swc/helpers@0.5.15))(@types/node@18.18.4)(typescript@5.2.2)):
dependencies:
'@babel/core': 7.26.0
@@ -29712,6 +29796,68 @@ snapshots:
- babel-plugin-macros
- supports-color
jest-config@29.7.0(@types/node@18.18.4)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2)):
dependencies:
'@babel/core': 7.26.0
'@jest/test-sequencer': 29.7.0
'@jest/types': 29.6.3
babel-jest: 29.7.0(@babel/core@7.26.0)
chalk: 4.1.2
ci-info: 3.8.0
deepmerge: 4.3.1
glob: 7.2.3
graceful-fs: 4.2.11
jest-circus: 29.7.0
jest-environment-node: 29.7.0
jest-get-type: 29.6.3
jest-regex-util: 29.6.3
jest-resolve: 29.7.0
jest-runner: 29.7.0
jest-util: 29.7.0
jest-validate: 29.7.0
micromatch: 4.0.8
parse-json: 5.2.0
pretty-format: 29.7.0
slash: 3.0.0
strip-json-comments: 3.1.1
optionalDependencies:
'@types/node': 18.18.4
ts-node: 10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2)
transitivePeerDependencies:
- babel-plugin-macros
- supports-color
jest-config@29.7.0(@types/node@22.15.17)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2)):
dependencies:
'@babel/core': 7.26.0
'@jest/test-sequencer': 29.7.0
'@jest/types': 29.6.3
babel-jest: 29.7.0(@babel/core@7.26.0)
chalk: 4.1.2
ci-info: 3.8.0
deepmerge: 4.3.1
glob: 7.2.3
graceful-fs: 4.2.11
jest-circus: 29.7.0
jest-environment-node: 29.7.0
jest-get-type: 29.6.3
jest-regex-util: 29.6.3
jest-resolve: 29.7.0
jest-runner: 29.7.0
jest-util: 29.7.0
jest-validate: 29.7.0
micromatch: 4.0.8
parse-json: 5.2.0
pretty-format: 29.7.0
slash: 3.0.0
strip-json-comments: 3.1.1
optionalDependencies:
'@types/node': 22.15.17
ts-node: 10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2)
transitivePeerDependencies:
- babel-plugin-macros
- supports-color
jest-diff@29.7.0:
dependencies:
chalk: 4.1.2
@@ -29826,7 +29972,7 @@ snapshots:
jest-playwright-preset@4.0.0(jest-circus@29.7.0)(jest-environment-node@29.7.0)(jest-runner@29.7.0)(jest@29.7.0):
dependencies:
expect-playwright: 0.8.0
jest: 29.7.0(@types/node@18.18.4)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@18.18.4)(typescript@5.2.2))
jest: 29.7.0
jest-circus: 29.7.0
jest-environment-node: 29.7.0
jest-process-manager: 0.4.0
@@ -29984,7 +30130,7 @@ snapshots:
dependencies:
ansi-escapes: 6.0.0
chalk: 5.4.1
jest: 29.7.0(@types/node@18.18.4)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@18.18.4)(typescript@5.2.2))
jest: 29.7.0
jest-regex-util: 29.6.3
jest-watcher: 29.7.0
slash: 5.1.0
@@ -30015,6 +30161,18 @@ snapshots:
merge-stream: 2.0.0
supports-color: 8.1.1
jest@29.7.0:
dependencies:
'@jest/core': 29.7.0(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@18.18.4)(typescript@5.2.2))
'@jest/types': 29.6.3
import-local: 3.1.0
jest-cli: 29.7.0
transitivePeerDependencies:
- '@types/node'
- babel-plugin-macros
- supports-color
- ts-node
jest@29.7.0(@types/node@18.18.4)(ts-node@10.9.1(@swc/core@1.10.14(@swc/helpers@0.5.15))(@types/node@18.18.4)(typescript@5.2.2)):
dependencies:
'@jest/core': 29.7.0(ts-node@10.9.1(@swc/core@1.10.14(@swc/helpers@0.5.15))(@types/node@18.18.4)(typescript@5.2.2))
@@ -30039,6 +30197,18 @@ snapshots:
- supports-color
- ts-node
jest@29.7.0(@types/node@22.15.17)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2)):
dependencies:
'@jest/core': 29.7.0(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2))
'@jest/types': 29.6.3
import-local: 3.1.0
jest-cli: 29.7.0(@types/node@22.15.17)(ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2))
transitivePeerDependencies:
- '@types/node'
- babel-plugin-macros
- supports-color
- ts-node
jiti@2.4.2: {}
jmespath@0.16.0: {}
@@ -32166,16 +32336,6 @@ snapshots:
'@csstools/utilities': 2.0.0(postcss@8.5.2)
postcss: 8.5.2
postcss-loader@4.3.0(postcss@8.5.4)(webpack@5.88.2):
dependencies:
cosmiconfig: 7.1.0
klona: 2.0.5
loader-utils: 2.0.4
postcss: 8.5.4
schema-utils: 3.3.0
semver: 7.7.0
webpack: 5.88.2(@swc/core@1.11.4(@swc/helpers@0.5.15))(esbuild@0.18.20)(webpack-cli@5.1.4)
postcss-loader@4.3.0(postcss@8.5.6)(webpack@5.88.2):
dependencies:
cosmiconfig: 7.1.0
@@ -32184,7 +32344,7 @@ snapshots:
postcss: 8.5.6
schema-utils: 3.3.0
semver: 7.7.0
webpack: 5.88.2
webpack: 5.88.2(@swc/core@1.11.4(@swc/helpers@0.5.15))(esbuild@0.18.20)(webpack-cli@5.1.4)
postcss-logical@8.0.0(postcss@8.5.2):
dependencies:
@@ -32281,9 +32441,9 @@ snapshots:
dependencies:
postcss: 7.0.39
postcss-modules-extract-imports@3.0.0(postcss@8.5.4):
postcss-modules-extract-imports@3.0.0(postcss@8.5.6):
dependencies:
postcss: 8.5.4
postcss: 8.5.6
postcss-modules-local-by-default@3.0.3:
dependencies:
@@ -32292,10 +32452,10 @@ snapshots:
postcss-selector-parser: 6.1.2
postcss-value-parser: 4.2.0
postcss-modules-local-by-default@4.0.3(postcss@8.5.4):
postcss-modules-local-by-default@4.0.3(postcss@8.5.6):
dependencies:
icss-utils: 5.1.0(postcss@8.5.4)
postcss: 8.5.4
icss-utils: 5.1.0(postcss@8.5.6)
postcss: 8.5.6
postcss-selector-parser: 6.1.2
postcss-value-parser: 4.2.0
@@ -32304,9 +32464,9 @@ snapshots:
postcss: 7.0.39
postcss-selector-parser: 6.1.2
postcss-modules-scope@3.0.0(postcss@8.5.4):
postcss-modules-scope@3.0.0(postcss@8.5.6):
dependencies:
postcss: 8.5.4
postcss: 8.5.6
postcss-selector-parser: 6.1.2
postcss-modules-values@3.0.0:
@@ -32314,10 +32474,10 @@ snapshots:
icss-utils: 4.1.1
postcss: 7.0.39
postcss-modules-values@4.0.0(postcss@8.5.4):
postcss-modules-values@4.0.0(postcss@8.5.6):
dependencies:
icss-utils: 5.1.0(postcss@8.5.4)
postcss: 8.5.4
icss-utils: 5.1.0(postcss@8.5.6)
postcss: 8.5.6
postcss-nesting@13.0.1(postcss@8.5.2):
dependencies:
@@ -32637,12 +32797,6 @@ snapshots:
picocolors: 1.1.1
source-map-js: 1.2.1
postcss@8.5.4:
dependencies:
nanoid: 3.3.11
picocolors: 1.1.1
source-map-js: 1.2.1
postcss@8.5.6:
dependencies:
nanoid: 3.3.11
@@ -35273,6 +35427,27 @@ snapshots:
optionalDependencies:
'@swc/core': 1.11.4(@swc/helpers@0.5.15)
ts-node@10.9.1(@swc/core@1.11.4(@swc/helpers@0.5.15))(@types/node@22.15.17)(typescript@5.2.2):
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.9
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.3
'@types/node': 22.15.17
acorn: 8.10.0
acorn-walk: 8.2.0
arg: 4.1.3
create-require: 1.1.1
diff: 4.0.2
make-error: 1.3.6
typescript: 5.2.2
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
optionalDependencies:
'@swc/core': 1.11.4(@swc/helpers@0.5.15)
optional: true
ts-pattern@4.3.0: {}
ts-toolbelt@9.6.0: {}