@yuants/app-virtual-exchange 0.18.5 → 0.18.7

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 (92) hide show
  1. package/dist/app-virtual-exchange.d.ts +1 -0
  2. package/dist/credential.js.map +1 -1
  3. package/dist/legacy-services.js.map +1 -1
  4. package/dist/position.js.map +1 -1
  5. package/dist/quote/__tests__/implementations.test.js +1 -1
  6. package/dist/quote/__tests__/implementations.test.js.map +1 -1
  7. package/dist/quote/benchmark/ForkedQuoteStateComparisonTest.js.map +1 -1
  8. package/dist/quote/benchmark/PerformanceTester.js.map +1 -1
  9. package/dist/quote/benchmark/QuoteStateComparisonTest.js.map +1 -1
  10. package/dist/quote/benchmark/QuoteStateTestRunner.js.map +1 -1
  11. package/dist/quote/benchmark/index.js.map +1 -1
  12. package/dist/quote/benchmark/test-helpers.js.map +1 -1
  13. package/dist/quote/benchmark/worker.js.map +1 -1
  14. package/dist/quote/implementations/v0.js.map +1 -1
  15. package/dist/quote/implementations/v1.js.map +1 -1
  16. package/dist/quote/implementations/v2.js.map +1 -1
  17. package/dist/quote/implementations/v3.js +1 -1
  18. package/dist/quote/implementations/v3.js.map +1 -1
  19. package/dist/quote/scheduler.js.map +1 -1
  20. package/dist/quote/service.js.map +1 -1
  21. package/dist/quote/state.benchmark.js.map +1 -1
  22. package/dist/series-collector/backwards-interest-rate.js.map +1 -1
  23. package/dist/series-collector/backwards-ohlc.js.map +1 -1
  24. package/dist/series-collector/discovery.js.map +1 -1
  25. package/dist/series-collector/forwards-interest-rate.js.map +1 -1
  26. package/dist/series-collector/forwards-ohlc.js.map +1 -1
  27. package/dist/series-collector/patch-interest-rate.js.map +1 -1
  28. package/dist/series-collector/patch-ohlc.js.map +1 -1
  29. package/dist/series-collector/setup.js.map +1 -1
  30. package/dist/series-data/fifo-queue.js.map +1 -1
  31. package/dist/series-data/scheduler.js.map +1 -1
  32. package/lib/credential.d.ts.map +1 -1
  33. package/lib/credential.js.map +1 -1
  34. package/lib/legacy-services.js.map +1 -1
  35. package/lib/position.d.ts.map +1 -1
  36. package/lib/position.js.map +1 -1
  37. package/lib/quote/__tests__/implementations.test.js +1 -1
  38. package/lib/quote/__tests__/implementations.test.js.map +1 -1
  39. package/lib/quote/benchmark/ForkedQuoteStateComparisonTest.js.map +1 -1
  40. package/lib/quote/benchmark/PerformanceTester.d.ts +0 -1
  41. package/lib/quote/benchmark/PerformanceTester.d.ts.map +1 -1
  42. package/lib/quote/benchmark/PerformanceTester.js.map +1 -1
  43. package/lib/quote/benchmark/QuoteStateComparisonTest.js.map +1 -1
  44. package/lib/quote/benchmark/QuoteStateTestRunner.js.map +1 -1
  45. package/lib/quote/benchmark/index.js +2 -2
  46. package/lib/quote/benchmark/index.js.map +1 -1
  47. package/lib/quote/benchmark/test-helpers.js +4 -5
  48. package/lib/quote/benchmark/test-helpers.js.map +1 -1
  49. package/lib/quote/benchmark/worker.js.map +1 -1
  50. package/lib/quote/implementations/v0.js +1 -2
  51. package/lib/quote/implementations/v0.js.map +1 -1
  52. package/lib/quote/implementations/v1.js.map +1 -1
  53. package/lib/quote/implementations/v2.js.map +1 -1
  54. package/lib/quote/implementations/v3.js +1 -1
  55. package/lib/quote/implementations/v3.js.map +1 -1
  56. package/lib/quote/scheduler.d.ts.map +1 -1
  57. package/lib/quote/scheduler.js.map +1 -1
  58. package/lib/quote/service.js.map +1 -1
  59. package/lib/quote/state.benchmark.js.map +1 -1
  60. package/lib/quote/types.d.ts +2 -2
  61. package/lib/quote/types.d.ts.map +1 -1
  62. package/lib/series-collector/backwards-interest-rate.d.ts +1 -2
  63. package/lib/series-collector/backwards-interest-rate.d.ts.map +1 -1
  64. package/lib/series-collector/backwards-interest-rate.js.map +1 -1
  65. package/lib/series-collector/backwards-ohlc.d.ts +1 -2
  66. package/lib/series-collector/backwards-ohlc.d.ts.map +1 -1
  67. package/lib/series-collector/backwards-ohlc.js.map +1 -1
  68. package/lib/series-collector/discovery.js.map +1 -1
  69. package/lib/series-collector/forwards-interest-rate.d.ts +1 -2
  70. package/lib/series-collector/forwards-interest-rate.d.ts.map +1 -1
  71. package/lib/series-collector/forwards-interest-rate.js.map +1 -1
  72. package/lib/series-collector/forwards-ohlc.d.ts +1 -2
  73. package/lib/series-collector/forwards-ohlc.d.ts.map +1 -1
  74. package/lib/series-collector/forwards-ohlc.js.map +1 -1
  75. package/lib/series-collector/patch-interest-rate.d.ts +1 -2
  76. package/lib/series-collector/patch-interest-rate.d.ts.map +1 -1
  77. package/lib/series-collector/patch-interest-rate.js.map +1 -1
  78. package/lib/series-collector/patch-ohlc.d.ts +1 -2
  79. package/lib/series-collector/patch-ohlc.d.ts.map +1 -1
  80. package/lib/series-collector/patch-ohlc.js.map +1 -1
  81. package/lib/series-collector/setup.js.map +1 -1
  82. package/lib/series-collector/sql-helpers.d.ts.map +1 -1
  83. package/lib/series-data/fifo-queue.d.ts.map +1 -1
  84. package/lib/series-data/fifo-queue.js.map +1 -1
  85. package/lib/series-data/scheduler.js.map +1 -1
  86. package/lib/tsdoc-metadata.json +11 -0
  87. package/package.json +42 -42
  88. package/temp/app-virtual-exchange.api.json +193 -0
  89. package/temp/app-virtual-exchange.api.md +9 -0
  90. package/temp/build/typescript/ts_KjrfbUqK.json +1 -0
  91. package/temp/test/jest/haste-map-76b16e3ab892e2fd05068740b7223d57-a6c52f003baf5bf33cffc52364f3bd7a-4ce9ff2cd20d69bbaecd1543c7e32e02 +0 -0
  92. package/temp/test/jest/perf-cache-76b16e3ab892e2fd05068740b7223d57-da39a3ee5e6b4b0d3255bfef95601890 +1 -0
@@ -0,0 +1 @@
1
+ export { }
@@ -1 +1 @@
1
- {"version":3,"file":"credential.js","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCache } from '@yuants/cache';\nimport { getCredentialId } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { ISecret, listSecrets, readSecret, writeSecret } from '@yuants/secret';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { newError } from '@yuants/utils';\nimport { defer, firstValueFrom, map, repeat, retry, shareReplay } from 'rxjs';\n\ninterface IExchangeCredential {\n type: string;\n payload: any;\n}\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst credentialReader = process.env.NODE_UNIT_PUBLIC_KEY || terminal.keyPair.public_key;\n\n/**\n * 根据 secret sign 解析出对应的 exchange credential\n * 此处可以做缓存,因为同一个 secret sign 对应的 credential 信息永远不会变化,可以节约解密和后续 SQL 查询的开销\n * 得到 credential 后,此 credential 不一定是有效的,因为可能凭证信息已经过期或被撤销\n */\nconst secretSignToCredentialIdCache = createCache(async (sign: string) => {\n const sql = `SELECT * FROM secret WHERE sign = ${escapeSQL(sign)} LIMIT 1;`;\n const res = await requestSQL<ISecret[]>(terminal, sql);\n if (res.length === 0) throw newError('SECRET_NOT_FOUND', { sign });\n const secret = res[0];\n const decrypted = await readSecret(terminal, secret);\n const credential = JSON.parse(new TextDecoder().decode(decrypted)) as IExchangeCredential;\n return credential;\n});\n\n/**\n * 根据 credential 信息解析出对应的 credential ID\n * 此处可以做缓存,因为同一个 credential 永远对应同一个 credential ID,可以节约后续 SQL 查询的开销\n * 但是需要注意的是,credential ID 可能会因为凭证被撤销而失效,但是可以在下游调用其他服务时感知到,因此可以永久缓存\n */\nconst credentialIdCache = createCache(async (credentialKey: string) => {\n const credential = JSON.parse(credentialKey) as IExchangeCredential;\n const res = await getCredentialId(terminal, credential);\n return res.data;\n});\n\nconst listAllCredentials = async () => {\n const secrets = await listSecrets(terminal, {\n reader: credentialReader,\n tags: { type: 'exchange_credential' },\n });\n\n const results = await Promise.allSettled(secrets.map((secret) => getCredentialBySecretId(secret.sign)));\n return results.map(\n (\n result,\n index,\n ): {\n sign: string;\n credential: IExchangeCredential | null;\n credentialId: string | null;\n error: any;\n } => {\n if (result.status === 'fulfilled') {\n return {\n sign: secrets[index].sign,\n credential: result.value.credential,\n credentialId: result.value.credentialId,\n error: null,\n };\n } else {\n return {\n sign: secrets[index].sign,\n credential: null,\n credentialId: null,\n error: `${result.reason}`,\n };\n }\n },\n );\n};\n\nterminal.server.provideService<IExchangeCredential, ISecret>(\n 'VEX/RegisterExchangeCredential',\n {\n type: 'object',\n required: ['type', 'payload'],\n properties: {\n type: { type: 'string' },\n payload: { type: 'object' },\n },\n },\n async (msg) => {\n const credential = msg.req;\n const secretData = new TextEncoder().encode(JSON.stringify(credential));\n const secret = await writeSecret(terminal, credentialReader, { type: 'exchange_credential' }, secretData);\n return { res: { code: 0, message: 'OK', data: secret } };\n },\n);\n\n// For Debugging Purpose\nterminal.server.provideService('VEX/ListExchangeCredential', {}, async () => {\n return { res: { code: 0, message: 'OK', data: await listAllCredentials() } };\n});\n\nterminal.server.provideService<void, string[]>('VEX/ListCredentials', {}, async () => {\n const credentials = await firstValueFrom(validCredentials$);\n return { res: { code: 0, message: 'OK', data: [...credentials.keys()] } };\n});\n\nexport const validCredentials$ = defer(() => listAllCredentials()).pipe(\n map((x) => {\n const map = new Map<string, IExchangeCredential>();\n if (!x) return map;\n for (const xx of x) {\n if (xx.credentialId && xx.credential) {\n map.set(xx.credentialId, xx.credential);\n }\n }\n return map;\n }),\n repeat({ delay: 10000 }),\n retry({ delay: 5000 }),\n shareReplay(1),\n);\n\nexport const validCredentialTypes$ = validCredentials$.pipe(\n map((credentials) => {\n const types = new Set<string>();\n credentials.forEach((credential) => {\n types.add(credential.type);\n });\n return Array.from(types);\n }),\n);\n\n/**\n * 根据 secret sign 解析出对应的 credential 以及 credential ID\n * @param sign - secret sign\n * @returns 解析得到的 credential 以及对应的 credential ID\n * @throws 如果无法解析出对应的 credential 或 credential ID,则抛出异常\n *\n * 不依赖 List Credential 服务,可以及时感知凭证的新增和变更\n */\nexport const getCredentialBySecretId = async (sign: string) => {\n const credential = await secretSignToCredentialIdCache.query(sign);\n if (!credential) throw newError('CREDENTIAL_NOT_RESOLVED', { sign });\n const credentialId = await credentialIdCache.query(JSON.stringify(credential));\n if (!credentialId) throw newError('CREDENTIAL_ID_NOT_RESOLVED', { sign });\n return { sign, credential, credentialId };\n};\n"]}
1
+ {"version":3,"file":"credential.js","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCache } from '@yuants/cache';\nimport { getCredentialId } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { ISecret, listSecrets, readSecret, writeSecret } from '@yuants/secret';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { newError } from '@yuants/utils';\nimport { defer, firstValueFrom, map, repeat, retry, shareReplay } from 'rxjs';\n\ninterface IExchangeCredential {\n type: string;\n payload: any;\n}\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst credentialReader = process.env.NODE_UNIT_PUBLIC_KEY || terminal.keyPair.public_key;\n\n/**\n * 根据 secret sign 解析出对应的 exchange credential\n * 此处可以做缓存,因为同一个 secret sign 对应的 credential 信息永远不会变化,可以节约解密和后续 SQL 查询的开销\n * 得到 credential 后,此 credential 不一定是有效的,因为可能凭证信息已经过期或被撤销\n */\nconst secretSignToCredentialIdCache = createCache(async (sign: string) => {\n const sql = `SELECT * FROM secret WHERE sign = ${escapeSQL(sign)} LIMIT 1;`;\n const res = await requestSQL<ISecret[]>(terminal, sql);\n if (res.length === 0) throw newError('SECRET_NOT_FOUND', { sign });\n const secret = res[0];\n const decrypted = await readSecret(terminal, secret);\n const credential = JSON.parse(new TextDecoder().decode(decrypted)) as IExchangeCredential;\n return credential;\n});\n\n/**\n * 根据 credential 信息解析出对应的 credential ID\n * 此处可以做缓存,因为同一个 credential 永远对应同一个 credential ID,可以节约后续 SQL 查询的开销\n * 但是需要注意的是,credential ID 可能会因为凭证被撤销而失效,但是可以在下游调用其他服务时感知到,因此可以永久缓存\n */\nconst credentialIdCache = createCache(async (credentialKey: string) => {\n const credential = JSON.parse(credentialKey) as IExchangeCredential;\n const res = await getCredentialId(terminal, credential);\n return res.data;\n});\n\nconst listAllCredentials = async () => {\n const secrets = await listSecrets(terminal, {\n reader: credentialReader,\n tags: { type: 'exchange_credential' },\n });\n\n const results = await Promise.allSettled(secrets.map((secret) => getCredentialBySecretId(secret.sign)));\n return results.map(\n (\n result,\n index,\n ): {\n sign: string;\n credential: IExchangeCredential | null;\n credentialId: string | null;\n error: any;\n } => {\n if (result.status === 'fulfilled') {\n return {\n sign: secrets[index].sign,\n credential: result.value.credential,\n credentialId: result.value.credentialId,\n error: null,\n };\n } else {\n return {\n sign: secrets[index].sign,\n credential: null,\n credentialId: null,\n error: `${result.reason}`,\n };\n }\n },\n );\n};\n\nterminal.server.provideService<IExchangeCredential, ISecret>(\n 'VEX/RegisterExchangeCredential',\n {\n type: 'object',\n required: ['type', 'payload'],\n properties: {\n type: { type: 'string' },\n payload: { type: 'object' },\n },\n },\n async (msg) => {\n const credential = msg.req;\n const secretData = new TextEncoder().encode(JSON.stringify(credential));\n const secret = await writeSecret(terminal, credentialReader, { type: 'exchange_credential' }, secretData);\n return { res: { code: 0, message: 'OK', data: secret } };\n },\n);\n\n// For Debugging Purpose\nterminal.server.provideService('VEX/ListExchangeCredential', {}, async () => {\n return { res: { code: 0, message: 'OK', data: await listAllCredentials() } };\n});\n\nterminal.server.provideService<void, string[]>('VEX/ListCredentials', {}, async () => {\n const credentials = await firstValueFrom(validCredentials$);\n return { res: { code: 0, message: 'OK', data: [...credentials.keys()] } };\n});\n\nexport const validCredentials$ = defer(() => listAllCredentials()).pipe(\n map((x) => {\n const map = new Map<string, IExchangeCredential>();\n if (!x) return map;\n for (const xx of x) {\n if (xx.credentialId && xx.credential) {\n map.set(xx.credentialId, xx.credential);\n }\n }\n return map;\n }),\n repeat({ delay: 10000 }),\n retry({ delay: 5000 }),\n shareReplay(1),\n);\n\nexport const validCredentialTypes$ = validCredentials$.pipe(\n map((credentials) => {\n const types = new Set<string>();\n credentials.forEach((credential) => {\n types.add(credential.type);\n });\n return Array.from(types);\n }),\n);\n\n/**\n * 根据 secret sign 解析出对应的 credential 以及 credential ID\n * @param sign - secret sign\n * @returns 解析得到的 credential 以及对应的 credential ID\n * @throws 如果无法解析出对应的 credential 或 credential ID,则抛出异常\n *\n * 不依赖 List Credential 服务,可以及时感知凭证的新增和变更\n */\nexport const getCredentialBySecretId = async (sign: string) => {\n const credential = await secretSignToCredentialIdCache.query(sign);\n if (!credential) throw newError('CREDENTIAL_NOT_RESOLVED', { sign });\n const credentialId = await credentialIdCache.query(JSON.stringify(credential));\n if (!credentialId) throw newError('CREDENTIAL_ID_NOT_RESOLVED', { sign });\n return { sign, credential, credentialId };\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"legacy-services.js","sourceRoot":"","sources":["../src/legacy-services.ts"],"names":[],"mappings":"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","sourcesContent":["import { provideAccountInfoService } from '@yuants/data-account';\nimport { IOrder, providePendingOrdersService } from '@yuants/data-order';\nimport { cancelOrder, getOrders, getPositions, modifyOrder, submitOrder } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { listWatch, newError } from '@yuants/utils';\nimport { map, Observable } from 'rxjs';\nimport { validCredentials$ } from './credential';\nimport { polyfillOrders, polyfillPosition } from './position';\n\nconst terminal = Terminal.fromNodeEnv();\n\nvalidCredentials$\n .pipe(\n map((x) => Array.from(x.entries())),\n listWatch(\n ([id]) => id,\n ([credential_id, credential]) =>\n new Observable((sub) => {\n console.info(`Setting up VEX services for credential: ${credential_id}`);\n // Setup AccountInfo Service\n {\n const service = provideAccountInfoService(\n terminal,\n credential_id,\n async () => {\n const res = await getPositions(terminal, credential);\n if (!res.data) throw newError('FETCH_POSITIONS_FAILED', { credential_id, res });\n const polyfilledPositions = await polyfillPosition(res.data);\n polyfilledPositions.forEach((pos) => {\n pos.account_id = credential_id;\n });\n return polyfilledPositions;\n },\n {\n auto_refresh_interval: 1000,\n },\n );\n sub.add(() => {\n service.dispose$.next();\n });\n }\n // Setup Pending Orders Service\n {\n const service = providePendingOrdersService(\n terminal,\n credential_id,\n async () => {\n const res = await getOrders(terminal, credential);\n if (!res.data) throw newError('FETCH_ORDERS_FAILED', { credential_id, res });\n\n res.data.forEach((order) => {\n order.account_id = credential_id;\n });\n\n await polyfillOrders(res.data);\n\n return res.data;\n },\n {\n auto_refresh_interval: 10000,\n },\n );\n sub.add(() => {\n service.dispose$.next();\n });\n }\n // Setup SubmitOrder Service\n {\n const service = terminal.server.provideService<IOrder, { order_id: string }>(\n 'SubmitOrder',\n {\n type: 'object',\n required: ['account_id'],\n properties: {\n account_id: { type: 'string', const: credential_id },\n },\n },\n async (msg) => {\n const [order] = await polyfillOrders([msg.req]);\n const res = await submitOrder(terminal, credential, order);\n return { res };\n },\n );\n sub.add(() => {\n service.dispose();\n });\n }\n\n // Setup ModifyOrder Service\n {\n const service = terminal.server.provideService<IOrder, void>(\n 'ModifyOrder',\n {\n type: 'object',\n required: ['account_id'],\n properties: {\n account_id: { type: 'string', const: credential_id },\n },\n },\n async (msg) => {\n const [order] = await polyfillOrders([msg.req]);\n const res = await modifyOrder(terminal, credential, order);\n return { res };\n },\n );\n sub.add(() => {\n service.dispose();\n });\n }\n\n // Setup CancelOrder Service\n {\n const service = terminal.server.provideService<IOrder, void>(\n 'CancelOrder',\n {\n type: 'object',\n required: ['account_id'],\n properties: {\n account_id: { type: 'string', const: credential_id },\n },\n },\n async (msg) => {\n const [order] = await polyfillOrders([msg.req]);\n const res = await cancelOrder(terminal, credential, order);\n return { res };\n },\n );\n sub.add(() => {\n service.dispose();\n });\n }\n }),\n ),\n )\n .subscribe();\n"]}
1
+ {"version":3,"file":"legacy-services.js","sourceRoot":"","sources":["../src/legacy-services.ts"],"names":[],"mappings":"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","sourcesContent":["import { provideAccountInfoService } from '@yuants/data-account';\nimport { IOrder, providePendingOrdersService } from '@yuants/data-order';\nimport { cancelOrder, getOrders, getPositions, modifyOrder, submitOrder } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { listWatch, newError } from '@yuants/utils';\nimport { map, Observable } from 'rxjs';\nimport { validCredentials$ } from './credential';\nimport { polyfillOrders, polyfillPosition } from './position';\n\nconst terminal = Terminal.fromNodeEnv();\n\nvalidCredentials$\n .pipe(\n map((x) => Array.from(x.entries())),\n listWatch(\n ([id]) => id,\n ([credential_id, credential]) =>\n new Observable((sub) => {\n console.info(`Setting up VEX services for credential: ${credential_id}`);\n // Setup AccountInfo Service\n {\n const service = provideAccountInfoService(\n terminal,\n credential_id,\n async () => {\n const res = await getPositions(terminal, credential);\n if (!res.data) throw newError('FETCH_POSITIONS_FAILED', { credential_id, res });\n const polyfilledPositions = await polyfillPosition(res.data);\n polyfilledPositions.forEach((pos) => {\n pos.account_id = credential_id;\n });\n return polyfilledPositions;\n },\n {\n auto_refresh_interval: 1000,\n },\n );\n sub.add(() => {\n service.dispose$.next();\n });\n }\n // Setup Pending Orders Service\n {\n const service = providePendingOrdersService(\n terminal,\n credential_id,\n async () => {\n const res = await getOrders(terminal, credential);\n if (!res.data) throw newError('FETCH_ORDERS_FAILED', { credential_id, res });\n\n res.data.forEach((order) => {\n order.account_id = credential_id;\n });\n\n await polyfillOrders(res.data);\n\n return res.data;\n },\n {\n auto_refresh_interval: 10000,\n },\n );\n sub.add(() => {\n service.dispose$.next();\n });\n }\n // Setup SubmitOrder Service\n {\n const service = terminal.server.provideService<IOrder, { order_id: string }>(\n 'SubmitOrder',\n {\n type: 'object',\n required: ['account_id'],\n properties: {\n account_id: { type: 'string', const: credential_id },\n },\n },\n async (msg) => {\n const [order] = await polyfillOrders([msg.req]);\n const res = await submitOrder(terminal, credential, order);\n return { res };\n },\n );\n sub.add(() => {\n service.dispose();\n });\n }\n\n // Setup ModifyOrder Service\n {\n const service = terminal.server.provideService<IOrder, void>(\n 'ModifyOrder',\n {\n type: 'object',\n required: ['account_id'],\n properties: {\n account_id: { type: 'string', const: credential_id },\n },\n },\n async (msg) => {\n const [order] = await polyfillOrders([msg.req]);\n const res = await modifyOrder(terminal, credential, order);\n return { res };\n },\n );\n sub.add(() => {\n service.dispose();\n });\n }\n\n // Setup CancelOrder Service\n {\n const service = terminal.server.provideService<IOrder, void>(\n 'CancelOrder',\n {\n type: 'object',\n required: ['account_id'],\n properties: {\n account_id: { type: 'string', const: credential_id },\n },\n },\n async (msg) => {\n const [order] = await polyfillOrders([msg.req]);\n const res = await cancelOrder(terminal, credential, order);\n return { res };\n },\n );\n sub.add(() => {\n service.dispose();\n });\n }\n }),\n ),\n )\n .subscribe();\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"position.js","sourceRoot":"","sources":["../src/position.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCache } from '@yuants/cache';\nimport { IPosition } from '@yuants/data-account';\nimport { IOrder } from '@yuants/data-order';\nimport { createClientProductCache } from '@yuants/data-product';\nimport { IQuote } from '@yuants/data-quote';\nimport { Terminal } from '@yuants/protocol';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { newError } from '@yuants/utils';\n\nconst terminal = Terminal.fromNodeEnv();\nconst productCache = createClientProductCache(terminal);\nconst quoteCache = createCache<IQuote>(\n async (product_id) => {\n const sql = `select * from quote where product_id = ${escapeSQL(product_id)}`;\n const [quote] = await requestSQL<IQuote[]>(terminal, sql);\n return quote;\n },\n { expire: 30_000 },\n);\n\nconst interestRateIntervalCache = createCache(\n async (product_id: string) => {\n const sql = `select created_at from interest_rate where series_id = ${escapeSQL(\n product_id,\n )} order by created_at desc limit 2`;\n const rates = await requestSQL<{ created_at: string }[]>(terminal, sql);\n if (rates.length < 2) return undefined;\n const prev = new Date(rates[0].created_at).getTime();\n const prevOfPrev = new Date(rates[1].created_at).getTime();\n const interval = prev - prevOfPrev;\n return {\n prev,\n prevOfPrev,\n interval,\n };\n },\n { swrAfter: 60_000, expire: 3600_000 },\n);\n\nexport const polyfillPosition = async (positions: IPosition[]): Promise<IPosition[]> => {\n // TODO: 使用 batch query SQL 优化 product / quote 查询性能\n for (const pos of positions) {\n const [theProduct, quote, interestRateInterval] = await Promise.all([\n productCache.query(pos.product_id),\n quoteCache.query(pos.product_id),\n interestRateIntervalCache.query(pos.product_id),\n ]);\n\n // 估值 = value_scale * volume * closable_price\n if (theProduct) {\n if (theProduct.base_currency) {\n pos.base_currency = theProduct.base_currency;\n }\n if (theProduct.quote_currency) {\n pos.quote_currency = theProduct.quote_currency;\n }\n if (pos.size === undefined && pos.volume !== undefined && pos.direction !== undefined) {\n pos.size = (pos.direction === 'LONG' ? 1 : -1) * pos.volume * (theProduct.value_scale || 1) + '';\n }\n if (pos.free_size === undefined && pos.free_volume !== undefined && pos.direction !== undefined) {\n pos.free_size =\n (pos.direction === 'LONG' ? 1 : -1) * pos.free_volume * (theProduct.value_scale || 1) + '';\n }\n pos.valuation = Math.abs((theProduct.value_scale || 1) * pos.volume * pos.closable_price);\n }\n\n if (quote && pos.size) {\n const sizeNum = +pos.size;\n if (pos.current_price === undefined) {\n if (sizeNum > 0) {\n // 多头头寸使用买一价作为可平仓价格,如果没有买一价则使用最新价\n pos.current_price = (quote.ask_price || quote.last_price) + '';\n } else {\n // 空头头寸使用卖一价作为可平仓价格,如果没有卖一价则使用最新价\n pos.current_price = (quote.bid_price || quote.last_price) + '';\n }\n }\n\n // 计算名义价值\n if (pos.notional === undefined) {\n pos.notional = sizeNum * (+pos.current_price || 0) + '';\n }\n }\n\n // 利率相关信息的追加\n if (quote) {\n // 优先使用 quote 表中的结算间隔\n if (quote.interest_rate_settlement_interval) {\n pos.settlement_interval = +quote.interest_rate_settlement_interval;\n }\n if (quote.interest_rate_next_settled_at !== null) {\n const nextSettledAt = new Date(quote.interest_rate_next_settled_at).getTime();\n // 优先使用行情数据中的下一个结算时间\n pos.settlement_scheduled_at = nextSettledAt;\n\n // 如果还没有结算周期,使用下一个结算时间推算结算间隔\n if (pos.settlement_interval === undefined && interestRateInterval !== undefined) {\n const interval = nextSettledAt - interestRateInterval.prev;\n pos.settlement_interval = interval;\n }\n } else if (quote.interest_rate_next_settled_at === null && interestRateInterval !== undefined) {\n // 估算下一个结算时间\n // 找到 prev + k * interval > now 的最小 k,则下一个结算时间为 prev + k * interval\n const k = Math.ceil((Date.now() - interestRateInterval.prev) / interestRateInterval.interval);\n pos.settlement_scheduled_at = interestRateInterval.prev + k * interestRateInterval.interval;\n }\n\n // 如果还没有结算间隔,则使用 interest rate 表的时间间隔作为结算间隔\n if (pos.settlement_interval === undefined && interestRateInterval) {\n pos.settlement_interval = interestRateInterval.interval;\n }\n\n if (pos.direction === 'LONG') {\n if (quote.interest_rate_long !== null) {\n pos.interest_to_settle = +quote.interest_rate_long * pos.valuation;\n }\n }\n if (pos.direction === 'SHORT') {\n if (quote.interest_rate_short !== null) {\n pos.interest_to_settle = +quote.interest_rate_short * pos.valuation;\n }\n }\n }\n }\n return positions;\n};\n\nexport const polyfillOrders = async (orders: IOrder[]): Promise<IOrder[]> => {\n for (const order of orders) {\n const theProduct = await productCache.query(order.product_id);\n if (theProduct) {\n if (order.size !== undefined) {\n const sizeNum = +order.size;\n const sizeStep = theProduct.volume_step * theProduct.value_scale;\n if (!(sizeStep > 0)) throw newError('INVALID_SIZE_STEP', { product: theProduct, sizeStep });\n // check size is multiple of sizeStep\n if (Math.abs(sizeNum - Math.round(sizeNum / sizeStep) * sizeStep) > 1e-16) {\n throw newError('INVALID_ORDER_SIZE_NOT_MULTIPLE_OF_SIZE_STEP', {\n order,\n sizeStep,\n sizeNum,\n product: theProduct,\n });\n }\n\n if (sizeNum >= 0) {\n order.order_direction = order.is_close ? 'CLOSE_SHORT' : 'OPEN_LONG';\n } else {\n order.order_direction = order.is_close ? 'CLOSE_LONG' : 'OPEN_SHORT';\n }\n order.volume = Math.abs(sizeNum) / theProduct.value_scale;\n }\n }\n }\n return orders;\n};\n"]}
1
+ {"version":3,"file":"position.js","sourceRoot":"","sources":["../src/position.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCache } from '@yuants/cache';\nimport { IPosition } from '@yuants/data-account';\nimport { IOrder } from '@yuants/data-order';\nimport { createClientProductCache } from '@yuants/data-product';\nimport { IQuote } from '@yuants/data-quote';\nimport { Terminal } from '@yuants/protocol';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { newError } from '@yuants/utils';\n\nconst terminal = Terminal.fromNodeEnv();\nconst productCache = createClientProductCache(terminal);\nconst quoteCache = createCache<IQuote>(\n async (product_id) => {\n const sql = `select * from quote where product_id = ${escapeSQL(product_id)}`;\n const [quote] = await requestSQL<IQuote[]>(terminal, sql);\n return quote;\n },\n { expire: 30_000 },\n);\n\nconst interestRateIntervalCache = createCache(\n async (product_id: string) => {\n const sql = `select created_at from interest_rate where series_id = ${escapeSQL(\n product_id,\n )} order by created_at desc limit 2`;\n const rates = await requestSQL<{ created_at: string }[]>(terminal, sql);\n if (rates.length < 2) return undefined;\n const prev = new Date(rates[0].created_at).getTime();\n const prevOfPrev = new Date(rates[1].created_at).getTime();\n const interval = prev - prevOfPrev;\n return {\n prev,\n prevOfPrev,\n interval,\n };\n },\n { swrAfter: 60_000, expire: 3600_000 },\n);\n\nexport const polyfillPosition = async (positions: IPosition[]): Promise<IPosition[]> => {\n // TODO: 使用 batch query SQL 优化 product / quote 查询性能\n for (const pos of positions) {\n const [theProduct, quote, interestRateInterval] = await Promise.all([\n productCache.query(pos.product_id),\n quoteCache.query(pos.product_id),\n interestRateIntervalCache.query(pos.product_id),\n ]);\n\n // 估值 = value_scale * volume * closable_price\n if (theProduct) {\n if (theProduct.base_currency) {\n pos.base_currency = theProduct.base_currency;\n }\n if (theProduct.quote_currency) {\n pos.quote_currency = theProduct.quote_currency;\n }\n if (pos.size === undefined && pos.volume !== undefined && pos.direction !== undefined) {\n pos.size = (pos.direction === 'LONG' ? 1 : -1) * pos.volume * (theProduct.value_scale || 1) + '';\n }\n if (pos.free_size === undefined && pos.free_volume !== undefined && pos.direction !== undefined) {\n pos.free_size =\n (pos.direction === 'LONG' ? 1 : -1) * pos.free_volume * (theProduct.value_scale || 1) + '';\n }\n pos.valuation = Math.abs((theProduct.value_scale || 1) * pos.volume * pos.closable_price);\n }\n\n if (quote && pos.size) {\n const sizeNum = +pos.size;\n if (pos.current_price === undefined) {\n if (sizeNum > 0) {\n // 多头头寸使用买一价作为可平仓价格,如果没有买一价则使用最新价\n pos.current_price = (quote.ask_price || quote.last_price) + '';\n } else {\n // 空头头寸使用卖一价作为可平仓价格,如果没有卖一价则使用最新价\n pos.current_price = (quote.bid_price || quote.last_price) + '';\n }\n }\n\n // 计算名义价值\n if (pos.notional === undefined) {\n pos.notional = sizeNum * (+pos.current_price || 0) + '';\n }\n }\n\n // 利率相关信息的追加\n if (quote) {\n // 优先使用 quote 表中的结算间隔\n if (quote.interest_rate_settlement_interval) {\n pos.settlement_interval = +quote.interest_rate_settlement_interval;\n }\n if (quote.interest_rate_next_settled_at !== null) {\n const nextSettledAt = new Date(quote.interest_rate_next_settled_at).getTime();\n // 优先使用行情数据中的下一个结算时间\n pos.settlement_scheduled_at = nextSettledAt;\n\n // 如果还没有结算周期,使用下一个结算时间推算结算间隔\n if (pos.settlement_interval === undefined && interestRateInterval !== undefined) {\n const interval = nextSettledAt - interestRateInterval.prev;\n pos.settlement_interval = interval;\n }\n } else if (quote.interest_rate_next_settled_at === null && interestRateInterval !== undefined) {\n // 估算下一个结算时间\n // 找到 prev + k * interval > now 的最小 k,则下一个结算时间为 prev + k * interval\n const k = Math.ceil((Date.now() - interestRateInterval.prev) / interestRateInterval.interval);\n pos.settlement_scheduled_at = interestRateInterval.prev + k * interestRateInterval.interval;\n }\n\n // 如果还没有结算间隔,则使用 interest rate 表的时间间隔作为结算间隔\n if (pos.settlement_interval === undefined && interestRateInterval) {\n pos.settlement_interval = interestRateInterval.interval;\n }\n\n if (pos.direction === 'LONG') {\n if (quote.interest_rate_long !== null) {\n pos.interest_to_settle = +quote.interest_rate_long * pos.valuation;\n }\n }\n if (pos.direction === 'SHORT') {\n if (quote.interest_rate_short !== null) {\n pos.interest_to_settle = +quote.interest_rate_short * pos.valuation;\n }\n }\n }\n }\n return positions;\n};\n\nexport const polyfillOrders = async (orders: IOrder[]): Promise<IOrder[]> => {\n for (const order of orders) {\n const theProduct = await productCache.query(order.product_id);\n if (theProduct) {\n if (order.size !== undefined) {\n const sizeNum = +order.size;\n const sizeStep = theProduct.volume_step * theProduct.value_scale;\n if (!(sizeStep > 0)) throw newError('INVALID_SIZE_STEP', { product: theProduct, sizeStep });\n // check size is multiple of sizeStep\n if (Math.abs(sizeNum - Math.round(sizeNum / sizeStep) * sizeStep) > 1e-16) {\n throw newError('INVALID_ORDER_SIZE_NOT_MULTIPLE_OF_SIZE_STEP', {\n order,\n sizeStep,\n sizeNum,\n product: theProduct,\n });\n }\n\n if (sizeNum >= 0) {\n order.order_direction = order.is_close ? 'CLOSE_SHORT' : 'OPEN_LONG';\n } else {\n order.order_direction = order.is_close ? 'CLOSE_LONG' : 'OPEN_SHORT';\n }\n order.volume = Math.abs(sizeNum) / theProduct.value_scale;\n }\n }\n }\n return orders;\n};\n"]}
@@ -92,7 +92,7 @@ describe('IQuoteState implementations', () => {
92
92
  quoteState.update({
93
93
  product_001: {
94
94
  last_price: ['100.0', 1000],
95
- ask_price: ['101.0', 2000],
95
+ ask_price: ['101.0', 2000], // 较新的时间戳
96
96
  bid_price: ['99.0', 500], // 较旧的时间戳
97
97
  },
98
98
  product_002: {
@@ -1 +1 @@
1
- {"version":3,"file":"implementations.test.js","sourceRoot":"","sources":["../../../src/quote/__tests__/implementations.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { implementations } from '../implementations';\nimport { IQuoteKey, IQuoteUpdateAction } from '../types';\n\n// 测试所有实现的通用测试套件\ndescribe('IQuoteState implementations', () => {\n // 测试每个实现\n Object.entries(implementations).forEach(([name, createQuoteState]) => {\n describe(`${name} implementation`, () => {\n let quoteState: ReturnType<typeof createQuoteState>;\n\n beforeEach(() => {\n quoteState = createQuoteState();\n });\n\n // 测试 1: 初始状态应该是空的\n it('should have empty initial state', () => {\n const dumped = quoteState.dumpAsObject();\n expect(dumped).toEqual({});\n });\n\n // 测试 2: 更新单个产品的单个字段\n it('should update single field for single product', () => {\n const updateAction: IQuoteUpdateAction = {\n product_001: {\n last_price: ['100.5', 1000],\n },\n };\n\n quoteState.update(updateAction);\n\n // 验证通过 getValueTuple 获取\n const tuple = quoteState.getValueTuple('product_001', 'last_price');\n expect(tuple).toEqual(['100.5', 1000]);\n\n // 验证 dumpAsObject\n const dumped = quoteState.dumpAsObject();\n expect(dumped).toEqual(updateAction);\n });\n\n // 测试 3: 更新多个产品和多个字段\n it('should update multiple fields for multiple products', () => {\n const updateAction: IQuoteUpdateAction = {\n product_001: {\n last_price: ['100.5', 1000],\n ask_price: ['101.0', 1001],\n },\n product_002: {\n bid_price: ['99.0', 1002],\n ask_volume: ['500', 1003],\n },\n };\n\n quoteState.update(updateAction);\n\n // 验证所有字段\n expect(quoteState.getValueTuple('product_001', 'last_price')).toEqual(['100.5', 1000]);\n expect(quoteState.getValueTuple('product_001', 'ask_price')).toEqual(['101.0', 1001]);\n expect(quoteState.getValueTuple('product_002', 'bid_price')).toEqual(['99.0', 1002]);\n expect(quoteState.getValueTuple('product_002', 'ask_volume')).toEqual(['500', 1003]);\n\n // 验证 dumpAsObject\n const dumped = quoteState.dumpAsObject();\n expect(dumped).toEqual(updateAction);\n });\n\n // 测试 4: 更新应该覆盖旧的时间戳,但忽略更旧的时间戳\n it('should overwrite with newer timestamp, ignore older timestamp', () => {\n // 初始更新\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n },\n });\n\n // 用更新的时间戳覆盖\n quoteState.update({\n product_001: {\n last_price: ['200.0', 2000],\n },\n });\n\n expect(quoteState.getValueTuple('product_001', 'last_price')).toEqual(['200.0', 2000]);\n\n // 用更旧的时间戳尝试覆盖(应该被忽略)\n quoteState.update({\n product_001: {\n last_price: ['300.0', 1500], // 时间戳 1500 比 2000 旧\n },\n });\n\n // 应该仍然是旧的值\n expect(quoteState.getValueTuple('product_001', 'last_price')).toEqual(['200.0', 2000]);\n });\n\n // 测试 5: 获取不存在的产品或字段应该返回 undefined\n it('should return undefined for non-existent product or field', () => {\n expect(quoteState.getValueTuple('non_existent', 'last_price')).toBeUndefined();\n\n // 添加一个产品但不包含该字段\n quoteState.update({\n product_001: {\n ask_price: ['101.0', 1000],\n },\n });\n\n expect(quoteState.getValueTuple('product_001', 'last_price')).toBeUndefined();\n expect(quoteState.getValueTuple('product_002', 'last_price')).toBeUndefined();\n });\n\n // 测试 6: filter 方法应该返回符合条件的数据\n it('should filter data by product_ids, fields, and updated_at', () => {\n // 设置测试数据\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n ask_price: ['101.0', 2000], // 较新的时间戳\n bid_price: ['99.0', 500], // 较旧的时间戳\n },\n product_002: {\n last_price: ['200.0', 1500],\n ask_price: ['201.0', 2500],\n },\n product_003: {\n last_price: ['300.0', 1200],\n },\n });\n\n // 测试 1: 过滤特定产品和字段,时间阈值 1000\n const result1 = quoteState.filter(['product_001', 'product_002'], ['last_price', 'ask_price'], 1000);\n\n expect(result1).toEqual({\n product_001: {\n last_price: ['100.0', 1000],\n ask_price: ['101.0', 2000],\n },\n product_002: {\n last_price: ['200.0', 1500],\n ask_price: ['201.0', 2500],\n },\n });\n\n // 测试 2: 过滤时间阈值 1500(排除较旧的数据)\n const result2 = quoteState.filter(\n ['product_001', 'product_002', 'product_003'],\n ['last_price', 'bid_price'],\n 1500,\n );\n\n expect(result2).toEqual({\n product_001: {\n // last_price 时间戳 1000 < 1500,应该被排除\n // bid_price 时间戳 500 < 1500,应该被排除\n },\n product_002: {\n last_price: ['200.0', 1500],\n },\n product_003: {\n // last_price 时间戳 1200 < 1500,应该被排除\n },\n });\n\n // 测试 3: 过滤不存在的产品应该返回空对象\n const result3 = quoteState.filter(['non_existent'], ['last_price'], 0);\n\n expect(result3).toEqual({\n non_existent: {},\n });\n });\n\n // 测试 7: 空更新不应该改变状态\n it('should handle empty update action', () => {\n // 先添加一些数据\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n },\n });\n\n const beforeDump = quoteState.dumpAsObject();\n\n // 空更新\n quoteState.update({});\n\n const afterDump = quoteState.dumpAsObject();\n expect(afterDump).toEqual(beforeDump);\n });\n\n // 测试 8: 更新时只提供部分字段,不应影响其他字段\n it('should not affect other fields when updating partial fields', () => {\n // 初始设置两个字段\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n ask_price: ['101.0', 1001],\n },\n });\n\n // 只更新一个字段\n quoteState.update({\n product_001: {\n last_price: ['200.0', 2000],\n },\n });\n\n // last_price 应该更新,ask_price 应该保持不变\n expect(quoteState.getValueTuple('product_001', 'last_price')).toEqual(['200.0', 2000]);\n expect(quoteState.getValueTuple('product_001', 'ask_price')).toEqual(['101.0', 1001]);\n });\n\n // 测试 9: 重复的更新应该保持幂等性\n it('should be idempotent for duplicate updates', () => {\n const updateAction: IQuoteUpdateAction = {\n product_001: {\n last_price: ['100.0', 1000],\n },\n };\n\n // 多次执行相同的更新\n quoteState.update(updateAction);\n quoteState.update(updateAction);\n quoteState.update(updateAction);\n\n // 状态应该与单次更新相同\n expect(quoteState.dumpAsObject()).toEqual(updateAction);\n });\n\n // 测试 10: 字段名称应该是 IQuoteKey 类型\n it('should handle all IQuoteKey field types', () => {\n const allFields: IQuoteKey[] = [\n 'last_price',\n 'ask_price',\n 'ask_volume',\n 'bid_volume',\n 'bid_price',\n 'interest_rate_short',\n 'open_interest',\n 'interest_rate_prev_settled_at',\n 'interest_rate_next_settled_at',\n 'interest_rate_long',\n ];\n\n const updateAction: IQuoteUpdateAction = {\n product_001: {},\n };\n\n // 为每个字段设置值\n allFields.forEach((field, index) => {\n updateAction['product_001'][field] = [`value_${index}`, 1000 + index];\n });\n\n quoteState.update(updateAction);\n\n // 验证每个字段\n allFields.forEach((field, index) => {\n expect(quoteState.getValueTuple('product_001', field)).toEqual([`value_${index}`, 1000 + index]);\n });\n\n // 验证 dumpAsObject\n const dumped = quoteState.dumpAsObject();\n expect(dumped).toEqual(updateAction);\n });\n\n // 测试 11: filterValues 方法应该返回值(即使字段不存在)\n it('should return values via filterValues (even if field missing)', () => {\n // 设置测试数据\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n ask_price: ['101.0', 2000],\n // bid_price not set\n },\n product_002: {\n last_price: ['200.0', 1500],\n },\n });\n\n // 测试 1: 获取存在的字段\n const result1 = quoteState.filterValues(['product_001', 'product_002'], ['last_price', 'ask_price']);\n expect(result1).toEqual({\n product_001: {\n last_price: '100.0',\n ask_price: '101.0',\n },\n product_002: {\n last_price: '200.0',\n ask_price: '',\n },\n });\n\n // 测试 2: 获取不存在的产品和字段\n const result2 = quoteState.filterValues(['product_001', 'non_existent'], ['last_price', 'bid_price']);\n expect(result2).toEqual({\n product_001: {\n last_price: '100.0',\n bid_price: '',\n },\n non_existent: {\n last_price: '',\n bid_price: '',\n },\n });\n\n // 测试 3: 空产品列表\n const result3 = quoteState.filterValues([], ['last_price']);\n expect(result3).toEqual({});\n\n // 测试 4: 空字段列表\n const result4 = quoteState.filterValues(['product_001'], []);\n expect(result4).toEqual({\n product_001: {},\n });\n\n // 测试 5: 所有字段类型\n const allFields: IQuoteKey[] = [\n 'last_price',\n 'ask_price',\n 'ask_volume',\n 'bid_volume',\n 'bid_price',\n 'interest_rate_short',\n 'open_interest',\n 'interest_rate_prev_settled_at',\n 'interest_rate_next_settled_at',\n 'interest_rate_long',\n ];\n const result5 = quoteState.filterValues(['product_001'], allFields);\n expect(Object.keys(result5.product_001)).toEqual(allFields);\n expect(result5.product_001.last_price).toBe('100.0');\n expect(result5.product_001.ask_price).toBe('101.0');\n // 其他字段应为空字符串\n expect(result5.product_001.bid_price).toBe('');\n expect(result5.product_001.ask_volume).toBe('');\n });\n });\n });\n});\n"]}
1
+ {"version":3,"file":"implementations.test.js","sourceRoot":"","sources":["../../../src/quote/__tests__/implementations.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { implementations } from '../implementations';\nimport { IQuoteKey, IQuoteUpdateAction } from '../types';\n\n// 测试所有实现的通用测试套件\ndescribe('IQuoteState implementations', () => {\n // 测试每个实现\n Object.entries(implementations).forEach(([name, createQuoteState]) => {\n describe(`${name} implementation`, () => {\n let quoteState: ReturnType<typeof createQuoteState>;\n\n beforeEach(() => {\n quoteState = createQuoteState();\n });\n\n // 测试 1: 初始状态应该是空的\n it('should have empty initial state', () => {\n const dumped = quoteState.dumpAsObject();\n expect(dumped).toEqual({});\n });\n\n // 测试 2: 更新单个产品的单个字段\n it('should update single field for single product', () => {\n const updateAction: IQuoteUpdateAction = {\n product_001: {\n last_price: ['100.5', 1000],\n },\n };\n\n quoteState.update(updateAction);\n\n // 验证通过 getValueTuple 获取\n const tuple = quoteState.getValueTuple('product_001', 'last_price');\n expect(tuple).toEqual(['100.5', 1000]);\n\n // 验证 dumpAsObject\n const dumped = quoteState.dumpAsObject();\n expect(dumped).toEqual(updateAction);\n });\n\n // 测试 3: 更新多个产品和多个字段\n it('should update multiple fields for multiple products', () => {\n const updateAction: IQuoteUpdateAction = {\n product_001: {\n last_price: ['100.5', 1000],\n ask_price: ['101.0', 1001],\n },\n product_002: {\n bid_price: ['99.0', 1002],\n ask_volume: ['500', 1003],\n },\n };\n\n quoteState.update(updateAction);\n\n // 验证所有字段\n expect(quoteState.getValueTuple('product_001', 'last_price')).toEqual(['100.5', 1000]);\n expect(quoteState.getValueTuple('product_001', 'ask_price')).toEqual(['101.0', 1001]);\n expect(quoteState.getValueTuple('product_002', 'bid_price')).toEqual(['99.0', 1002]);\n expect(quoteState.getValueTuple('product_002', 'ask_volume')).toEqual(['500', 1003]);\n\n // 验证 dumpAsObject\n const dumped = quoteState.dumpAsObject();\n expect(dumped).toEqual(updateAction);\n });\n\n // 测试 4: 更新应该覆盖旧的时间戳,但忽略更旧的时间戳\n it('should overwrite with newer timestamp, ignore older timestamp', () => {\n // 初始更新\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n },\n });\n\n // 用更新的时间戳覆盖\n quoteState.update({\n product_001: {\n last_price: ['200.0', 2000],\n },\n });\n\n expect(quoteState.getValueTuple('product_001', 'last_price')).toEqual(['200.0', 2000]);\n\n // 用更旧的时间戳尝试覆盖(应该被忽略)\n quoteState.update({\n product_001: {\n last_price: ['300.0', 1500], // 时间戳 1500 比 2000 旧\n },\n });\n\n // 应该仍然是旧的值\n expect(quoteState.getValueTuple('product_001', 'last_price')).toEqual(['200.0', 2000]);\n });\n\n // 测试 5: 获取不存在的产品或字段应该返回 undefined\n it('should return undefined for non-existent product or field', () => {\n expect(quoteState.getValueTuple('non_existent', 'last_price')).toBeUndefined();\n\n // 添加一个产品但不包含该字段\n quoteState.update({\n product_001: {\n ask_price: ['101.0', 1000],\n },\n });\n\n expect(quoteState.getValueTuple('product_001', 'last_price')).toBeUndefined();\n expect(quoteState.getValueTuple('product_002', 'last_price')).toBeUndefined();\n });\n\n // 测试 6: filter 方法应该返回符合条件的数据\n it('should filter data by product_ids, fields, and updated_at', () => {\n // 设置测试数据\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n ask_price: ['101.0', 2000], // 较新的时间戳\n bid_price: ['99.0', 500], // 较旧的时间戳\n },\n product_002: {\n last_price: ['200.0', 1500],\n ask_price: ['201.0', 2500],\n },\n product_003: {\n last_price: ['300.0', 1200],\n },\n });\n\n // 测试 1: 过滤特定产品和字段,时间阈值 1000\n const result1 = quoteState.filter(['product_001', 'product_002'], ['last_price', 'ask_price'], 1000);\n\n expect(result1).toEqual({\n product_001: {\n last_price: ['100.0', 1000],\n ask_price: ['101.0', 2000],\n },\n product_002: {\n last_price: ['200.0', 1500],\n ask_price: ['201.0', 2500],\n },\n });\n\n // 测试 2: 过滤时间阈值 1500(排除较旧的数据)\n const result2 = quoteState.filter(\n ['product_001', 'product_002', 'product_003'],\n ['last_price', 'bid_price'],\n 1500,\n );\n\n expect(result2).toEqual({\n product_001: {\n // last_price 时间戳 1000 < 1500,应该被排除\n // bid_price 时间戳 500 < 1500,应该被排除\n },\n product_002: {\n last_price: ['200.0', 1500],\n },\n product_003: {\n // last_price 时间戳 1200 < 1500,应该被排除\n },\n });\n\n // 测试 3: 过滤不存在的产品应该返回空对象\n const result3 = quoteState.filter(['non_existent'], ['last_price'], 0);\n\n expect(result3).toEqual({\n non_existent: {},\n });\n });\n\n // 测试 7: 空更新不应该改变状态\n it('should handle empty update action', () => {\n // 先添加一些数据\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n },\n });\n\n const beforeDump = quoteState.dumpAsObject();\n\n // 空更新\n quoteState.update({});\n\n const afterDump = quoteState.dumpAsObject();\n expect(afterDump).toEqual(beforeDump);\n });\n\n // 测试 8: 更新时只提供部分字段,不应影响其他字段\n it('should not affect other fields when updating partial fields', () => {\n // 初始设置两个字段\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n ask_price: ['101.0', 1001],\n },\n });\n\n // 只更新一个字段\n quoteState.update({\n product_001: {\n last_price: ['200.0', 2000],\n },\n });\n\n // last_price 应该更新,ask_price 应该保持不变\n expect(quoteState.getValueTuple('product_001', 'last_price')).toEqual(['200.0', 2000]);\n expect(quoteState.getValueTuple('product_001', 'ask_price')).toEqual(['101.0', 1001]);\n });\n\n // 测试 9: 重复的更新应该保持幂等性\n it('should be idempotent for duplicate updates', () => {\n const updateAction: IQuoteUpdateAction = {\n product_001: {\n last_price: ['100.0', 1000],\n },\n };\n\n // 多次执行相同的更新\n quoteState.update(updateAction);\n quoteState.update(updateAction);\n quoteState.update(updateAction);\n\n // 状态应该与单次更新相同\n expect(quoteState.dumpAsObject()).toEqual(updateAction);\n });\n\n // 测试 10: 字段名称应该是 IQuoteKey 类型\n it('should handle all IQuoteKey field types', () => {\n const allFields: IQuoteKey[] = [\n 'last_price',\n 'ask_price',\n 'ask_volume',\n 'bid_volume',\n 'bid_price',\n 'interest_rate_short',\n 'open_interest',\n 'interest_rate_prev_settled_at',\n 'interest_rate_next_settled_at',\n 'interest_rate_long',\n ];\n\n const updateAction: IQuoteUpdateAction = {\n product_001: {},\n };\n\n // 为每个字段设置值\n allFields.forEach((field, index) => {\n updateAction['product_001'][field] = [`value_${index}`, 1000 + index];\n });\n\n quoteState.update(updateAction);\n\n // 验证每个字段\n allFields.forEach((field, index) => {\n expect(quoteState.getValueTuple('product_001', field)).toEqual([`value_${index}`, 1000 + index]);\n });\n\n // 验证 dumpAsObject\n const dumped = quoteState.dumpAsObject();\n expect(dumped).toEqual(updateAction);\n });\n\n // 测试 11: filterValues 方法应该返回值(即使字段不存在)\n it('should return values via filterValues (even if field missing)', () => {\n // 设置测试数据\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n ask_price: ['101.0', 2000],\n // bid_price not set\n },\n product_002: {\n last_price: ['200.0', 1500],\n },\n });\n\n // 测试 1: 获取存在的字段\n const result1 = quoteState.filterValues(['product_001', 'product_002'], ['last_price', 'ask_price']);\n expect(result1).toEqual({\n product_001: {\n last_price: '100.0',\n ask_price: '101.0',\n },\n product_002: {\n last_price: '200.0',\n ask_price: '',\n },\n });\n\n // 测试 2: 获取不存在的产品和字段\n const result2 = quoteState.filterValues(['product_001', 'non_existent'], ['last_price', 'bid_price']);\n expect(result2).toEqual({\n product_001: {\n last_price: '100.0',\n bid_price: '',\n },\n non_existent: {\n last_price: '',\n bid_price: '',\n },\n });\n\n // 测试 3: 空产品列表\n const result3 = quoteState.filterValues([], ['last_price']);\n expect(result3).toEqual({});\n\n // 测试 4: 空字段列表\n const result4 = quoteState.filterValues(['product_001'], []);\n expect(result4).toEqual({\n product_001: {},\n });\n\n // 测试 5: 所有字段类型\n const allFields: IQuoteKey[] = [\n 'last_price',\n 'ask_price',\n 'ask_volume',\n 'bid_volume',\n 'bid_price',\n 'interest_rate_short',\n 'open_interest',\n 'interest_rate_prev_settled_at',\n 'interest_rate_next_settled_at',\n 'interest_rate_long',\n ];\n const result5 = quoteState.filterValues(['product_001'], allFields);\n expect(Object.keys(result5.product_001)).toEqual(allFields);\n expect(result5.product_001.last_price).toBe('100.0');\n expect(result5.product_001.ask_price).toBe('101.0');\n // 其他字段应为空字符串\n expect(result5.product_001.bid_price).toBe('');\n expect(result5.product_001.ask_volume).toBe('');\n });\n });\n });\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ForkedQuoteStateComparisonTest.js","sourceRoot":"","sources":["../../../src/quote/benchmark/ForkedQuoteStateComparisonTest.ts"],"names":[],"mappings":"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","sourcesContent":["import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { QuoteStateComparisonTest } from './QuoteStateComparisonTest';\nimport { PerformanceTester } from './PerformanceTester';\n\nconst execAsync = promisify(exec);\n\n/**\n * 使用子进程进行隔离内存测试的对比测试类\n * 每个实现都在独立的子进程中运行,确保内存测试的公平性\n */\nexport class ForkedQuoteStateComparisonTest {\n private nameA: string;\n private nameB: string;\n private workerScriptPath: string;\n\n constructor(\n nameA: string = 'Current',\n nameB: string = 'Baseline',\n workerScriptPath: string = __dirname + '/worker.ts',\n ) {\n this.nameA = nameA;\n this.nameB = nameB;\n this.workerScriptPath = workerScriptPath;\n }\n\n /**\n * 运行单个测试场景的子进程\n */\n private async runWorkerTest(\n implName: string,\n testType: string,\n productCount: number,\n extraArgs: Record<string, string> = {},\n ): Promise<any> {\n // 构建命令行参数\n const args = [`--impl=${implName}`, `--test=${testType}`, `--product-count=${productCount}`];\n\n // 添加额外参数\n for (const [key, value] of Object.entries(extraArgs)) {\n args.push(`--${key}=${value}`);\n }\n\n // 执行 worker 脚本,启用 GC 以进行公平的内存测试\n const command = `node --expose-gc $(which ts-node) ${this.workerScriptPath} ${args.join(' ')}`;\n\n try {\n const { stdout, stderr } = await execAsync(command);\n\n if (stderr && stderr.trim()) {\n console.error(`Worker stderr (${implName}, ${testType}, ${productCount}):`, stderr);\n }\n\n const result = JSON.parse(stdout.trim());\n\n if (!result.success) {\n // 子进程返回了失败结果\n return {\n success: false,\n error: result.error || 'Unknown error',\n impl: implName,\n test: testType,\n productCount,\n avgTime: null,\n time: null,\n heapUsedDiff: null,\n };\n }\n\n return result;\n } catch (error) {\n // 子进程执行失败(如 OOM killed、命令不存在等)\n console.error(`Worker execution failed (${implName}, ${testType}, ${productCount}):`, error);\n\n // 返回一个失败对象,而不是抛出错误\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n impl: implName,\n test: testType,\n productCount,\n avgTime: null,\n time: null,\n heapUsedDiff: null,\n };\n }\n }\n\n /**\n * 运行初始化测试对比\n */\n async runInitializationTestComparison(\n productCount: number,\n iterations: number = 3,\n ): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(`运行初始化对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品)`);\n\n const resultA = await this.runWorkerTest('current', 'init', productCount, {\n iterations: iterations.toString(),\n });\n const resultB = await this.runWorkerTest('baseline', 'init', productCount, {\n iterations: iterations.toString(),\n });\n\n return { resultA, resultB };\n }\n\n /**\n * 运行更新测试对比\n */\n async runUpdateTestComparison(\n productCount: number,\n updateCount: number,\n ): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(\n `运行更新对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品, ${updateCount} 更新)`,\n );\n\n const resultA = await this.runWorkerTest('current', 'update', productCount, {\n 'update-count': updateCount.toString(),\n });\n const resultB = await this.runWorkerTest('baseline', 'update', productCount, {\n 'update-count': updateCount.toString(),\n });\n\n return { resultA, resultB };\n }\n\n /**\n * 运行查询测试对比\n */\n async runQueryTestComparison(\n productCount: number,\n queryCount: number,\n ): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(\n `运行查询对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品, ${queryCount} 查询)`,\n );\n\n const resultA = await this.runWorkerTest('current', 'query', productCount, {\n 'query-count': queryCount.toString(),\n });\n const resultB = await this.runWorkerTest('baseline', 'query', productCount, {\n 'query-count': queryCount.toString(),\n });\n\n return { resultA, resultB };\n }\n\n /**\n * 运行过滤测试对比\n */\n async runFilterTestComparison(\n productCount: number,\n filterCount: number,\n ): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(\n `运行过滤对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品, ${filterCount} 过滤)`,\n );\n\n const resultA = await this.runWorkerTest('current', 'filter', productCount, {\n 'filter-count': filterCount.toString(),\n });\n const resultB = await this.runWorkerTest('baseline', 'filter', productCount, {\n 'filter-count': filterCount.toString(),\n });\n\n return { resultA, resultB };\n }\n\n /**\n * 运行转储测试对比\n */\n async runDumpTestComparison(productCount: number): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(`运行转储对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品)`);\n\n const resultA = await this.runWorkerTest('current', 'dump', productCount);\n const resultB = await this.runWorkerTest('baseline', 'dump', productCount);\n\n return { resultA, resultB };\n }\n\n /**\n * 打印对比结果(复用现有的对比结果打印逻辑)\n */\n private printComparisonResults(resultsA: any[], resultsB: any[], testType: string): void {\n // 创建一个临时的 QuoteStateComparisonTest 实例来复用其打印逻辑\n const tempComparison = new QuoteStateComparisonTest(\n () => {\n throw new Error('Not implemented');\n },\n () => {\n throw new Error('Not implemented');\n },\n this.nameA,\n this.nameB,\n );\n\n // 使用私有方法,需要类型断言来访问\n const privateMethod = (tempComparison as any).printComparisonResults;\n if (typeof privateMethod === 'function') {\n privateMethod.call(tempComparison, resultsA, resultsB, testType);\n } else {\n // 如果无法访问私有方法,使用简化版本\n console.log(`\\n${this.nameA} vs ${this.nameB} - ${testType} 对比结果:`);\n for (let i = 0; i < Math.min(resultsA.length, resultsB.length); i++) {\n const a = resultsA[i];\n const b = resultsB[i];\n\n // 检查是否有失败的测试\n const isAFailed = a.success === false;\n const isBFailed = b.success === false;\n\n if (isAFailed || isBFailed) {\n console.log(`\\n产品数量: ${a.productCount || b.productCount}`);\n\n if (isAFailed) {\n console.log(`❌ ${this.nameA} 测试失败: ${a.error || 'Unknown error'}`);\n } else {\n console.log(`${this.nameA}: ${a.avgTime || a.time}ms`);\n }\n\n if (isBFailed) {\n console.log(`❌ ${this.nameB} 测试失败: ${b.error || 'Unknown error'}`);\n } else {\n console.log(`${this.nameB}: ${b.avgTime || b.time}ms`);\n }\n\n // 打印内存使用(即使只有一个实现有数据)\n const memoryUsedA = a.heapUsedDiff;\n const memoryUsedB = b.heapUsedDiff;\n const hasMemoryA = memoryUsedA !== undefined && memoryUsedA !== null && !isNaN(memoryUsedA);\n const hasMemoryB = memoryUsedB !== undefined && memoryUsedB !== null && !isNaN(memoryUsedB);\n\n if (hasMemoryA || hasMemoryB) {\n console.log(`\\n内存使用:`);\n if (hasMemoryA) {\n console.log(`${this.nameA}: ${PerformanceTester.formatBytes(memoryUsedA)}`);\n }\n if (hasMemoryB) {\n console.log(`${this.nameB}: ${PerformanceTester.formatBytes(memoryUsedB)}`);\n }\n }\n\n console.log('-'.repeat(80));\n continue;\n }\n\n console.log(`产品数量 ${a.productCount}: ${a.avgTime || a.time}ms vs ${b.avgTime || b.time}ms`);\n\n // 打印内存使用(即使只有一个实现有数据)\n const memoryUsedA = a.heapUsedDiff;\n const memoryUsedB = b.heapUsedDiff;\n const hasMemoryA = memoryUsedA !== undefined && memoryUsedA !== null && !isNaN(memoryUsedA);\n const hasMemoryB = memoryUsedB !== undefined && memoryUsedB !== null && !isNaN(memoryUsedB);\n\n if (hasMemoryA || hasMemoryB) {\n console.log(`\\n内存使用:`);\n if (hasMemoryA) {\n console.log(`${this.nameA}: ${PerformanceTester.formatBytes(memoryUsedA)}`);\n }\n if (hasMemoryB) {\n console.log(`${this.nameB}: ${PerformanceTester.formatBytes(memoryUsedB)}`);\n }\n\n // 只有当两个实现都有有效内存数据时才进行对比\n if (hasMemoryA && hasMemoryB && memoryUsedA > 0 && memoryUsedB > 0) {\n const memoryRatio = memoryUsedA / memoryUsedB;\n const memoryPercentDiff = ((memoryRatio - 1) * 100).toFixed(2);\n if (memoryRatio > 1) {\n console.log(`${this.nameB} 节省 ${memoryPercentDiff}% 内存`);\n } else {\n console.log(`${this.nameA} 节省 ${(-parseFloat(memoryPercentDiff)).toFixed(2)}% 内存`);\n }\n }\n }\n\n console.log('-'.repeat(80));\n }\n }\n }\n\n /**\n * 运行完整的对比测试套件\n */\n async runComparisonTestSuite(): Promise<void> {\n console.log(`开始子进程隔离内存对比测试: ${this.nameA} vs ${this.nameB}`);\n console.log('注意:每个测试都在独立的子进程中运行,确保内存测试的公平性');\n\n const testScenarios = [\n {\n productCount: 10000,\n label: '10K',\n updateIterations: 1000,\n queryIterations: 10000,\n filterIterations: 1000,\n },\n {\n productCount: 100000,\n label: '100K',\n updateIterations: 100,\n queryIterations: 1000,\n filterIterations: 100,\n },\n {\n productCount: 1000000,\n label: '1M',\n updateIterations: 10,\n queryIterations: 100,\n filterIterations: 10,\n },\n ];\n\n // 初始化测试对比\n console.log('\\n运行初始化测试对比...');\n const initResultsA = [];\n const initResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const { resultA, resultB } = await this.runInitializationTestComparison(scenario.productCount, 3);\n initResultsA.push(resultA);\n initResultsB.push(resultB);\n } catch (error) {\n console.error(`初始化对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(initResultsA, initResultsB, '初始化测试');\n\n // 更新测试对比\n console.log('\\n运行更新测试对比...');\n const updateResultsA = [];\n const updateResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const { resultA, resultB } = await this.runUpdateTestComparison(\n scenario.productCount,\n scenario.updateIterations,\n );\n updateResultsA.push(resultA);\n updateResultsB.push(resultB);\n } catch (error) {\n console.error(`更新对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(updateResultsA, updateResultsB, '更新测试');\n\n // 查询测试对比\n console.log('\\n运行查询测试对比...');\n const queryResultsA = [];\n const queryResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const { resultA, resultB } = await this.runQueryTestComparison(\n scenario.productCount,\n scenario.queryIterations,\n );\n queryResultsA.push(resultA);\n queryResultsB.push(resultB);\n } catch (error) {\n console.error(`查询对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(queryResultsA, queryResultsB, '查询测试');\n\n // 过滤测试对比\n console.log('\\n运行过滤测试对比...');\n const filterResultsA = [];\n const filterResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const { resultA, resultB } = await this.runFilterTestComparison(\n scenario.productCount,\n scenario.filterIterations,\n );\n filterResultsA.push(resultA);\n filterResultsB.push(resultB);\n } catch (error) {\n console.error(`过滤对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(filterResultsA, filterResultsB, '过滤测试');\n\n // 转储测试对比\n console.log('\\n运行转储测试对比...');\n const dumpResultsA = [];\n const dumpResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const { resultA, resultB } = await this.runDumpTestComparison(scenario.productCount);\n dumpResultsA.push(resultA);\n dumpResultsB.push(resultB);\n } catch (error) {\n console.error(`转储对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(dumpResultsA, dumpResultsB, '转储测试');\n\n console.log('\\n子进程隔离内存对比测试完成!');\n }\n\n /**\n * 运行快速对比测试(仅测试小数据量)\n */\n async runQuickComparisonTest(): Promise<void> {\n console.log(`开始快速子进程对比测试: ${this.nameA} vs ${this.nameB}`);\n\n const quickScenarios = [\n {\n productCount: 1000,\n label: '1K',\n updateIterations: 100,\n queryIterations: 1000,\n filterIterations: 100,\n },\n { productCount: 10000, label: '10K', updateIterations: 10, queryIterations: 100, filterIterations: 10 },\n ];\n\n // 初始化测试对比\n console.log('\\n运行初始化测试对比...');\n const initResultsA = [];\n const initResultsB = [];\n for (const scenario of quickScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const { resultA, resultB } = await this.runInitializationTestComparison(scenario.productCount, 2);\n initResultsA.push(resultA);\n initResultsB.push(resultB);\n } catch (error) {\n console.error(`初始化对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(initResultsA, initResultsB, '快速初始化测试');\n\n console.log('\\n快速子进程对比测试完成!');\n }\n}\n"]}
1
+ {"version":3,"file":"ForkedQuoteStateComparisonTest.js","sourceRoot":"","sources":["../../../src/quote/benchmark/ForkedQuoteStateComparisonTest.ts"],"names":[],"mappings":"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","sourcesContent":["import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { QuoteStateComparisonTest } from './QuoteStateComparisonTest';\nimport { PerformanceTester } from './PerformanceTester';\n\nconst execAsync = promisify(exec);\n\n/**\n * 使用子进程进行隔离内存测试的对比测试类\n * 每个实现都在独立的子进程中运行,确保内存测试的公平性\n */\nexport class ForkedQuoteStateComparisonTest {\n private nameA: string;\n private nameB: string;\n private workerScriptPath: string;\n\n constructor(\n nameA: string = 'Current',\n nameB: string = 'Baseline',\n workerScriptPath: string = __dirname + '/worker.ts',\n ) {\n this.nameA = nameA;\n this.nameB = nameB;\n this.workerScriptPath = workerScriptPath;\n }\n\n /**\n * 运行单个测试场景的子进程\n */\n private async runWorkerTest(\n implName: string,\n testType: string,\n productCount: number,\n extraArgs: Record<string, string> = {},\n ): Promise<any> {\n // 构建命令行参数\n const args = [`--impl=${implName}`, `--test=${testType}`, `--product-count=${productCount}`];\n\n // 添加额外参数\n for (const [key, value] of Object.entries(extraArgs)) {\n args.push(`--${key}=${value}`);\n }\n\n // 执行 worker 脚本,启用 GC 以进行公平的内存测试\n const command = `node --expose-gc $(which ts-node) ${this.workerScriptPath} ${args.join(' ')}`;\n\n try {\n const { stdout, stderr } = await execAsync(command);\n\n if (stderr && stderr.trim()) {\n console.error(`Worker stderr (${implName}, ${testType}, ${productCount}):`, stderr);\n }\n\n const result = JSON.parse(stdout.trim());\n\n if (!result.success) {\n // 子进程返回了失败结果\n return {\n success: false,\n error: result.error || 'Unknown error',\n impl: implName,\n test: testType,\n productCount,\n avgTime: null,\n time: null,\n heapUsedDiff: null,\n };\n }\n\n return result;\n } catch (error) {\n // 子进程执行失败(如 OOM killed、命令不存在等)\n console.error(`Worker execution failed (${implName}, ${testType}, ${productCount}):`, error);\n\n // 返回一个失败对象,而不是抛出错误\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n impl: implName,\n test: testType,\n productCount,\n avgTime: null,\n time: null,\n heapUsedDiff: null,\n };\n }\n }\n\n /**\n * 运行初始化测试对比\n */\n async runInitializationTestComparison(\n productCount: number,\n iterations: number = 3,\n ): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(`运行初始化对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品)`);\n\n const resultA = await this.runWorkerTest('current', 'init', productCount, {\n iterations: iterations.toString(),\n });\n const resultB = await this.runWorkerTest('baseline', 'init', productCount, {\n iterations: iterations.toString(),\n });\n\n return { resultA, resultB };\n }\n\n /**\n * 运行更新测试对比\n */\n async runUpdateTestComparison(\n productCount: number,\n updateCount: number,\n ): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(\n `运行更新对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品, ${updateCount} 更新)`,\n );\n\n const resultA = await this.runWorkerTest('current', 'update', productCount, {\n 'update-count': updateCount.toString(),\n });\n const resultB = await this.runWorkerTest('baseline', 'update', productCount, {\n 'update-count': updateCount.toString(),\n });\n\n return { resultA, resultB };\n }\n\n /**\n * 运行查询测试对比\n */\n async runQueryTestComparison(\n productCount: number,\n queryCount: number,\n ): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(\n `运行查询对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品, ${queryCount} 查询)`,\n );\n\n const resultA = await this.runWorkerTest('current', 'query', productCount, {\n 'query-count': queryCount.toString(),\n });\n const resultB = await this.runWorkerTest('baseline', 'query', productCount, {\n 'query-count': queryCount.toString(),\n });\n\n return { resultA, resultB };\n }\n\n /**\n * 运行过滤测试对比\n */\n async runFilterTestComparison(\n productCount: number,\n filterCount: number,\n ): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(\n `运行过滤对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品, ${filterCount} 过滤)`,\n );\n\n const resultA = await this.runWorkerTest('current', 'filter', productCount, {\n 'filter-count': filterCount.toString(),\n });\n const resultB = await this.runWorkerTest('baseline', 'filter', productCount, {\n 'filter-count': filterCount.toString(),\n });\n\n return { resultA, resultB };\n }\n\n /**\n * 运行转储测试对比\n */\n async runDumpTestComparison(productCount: number): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(`运行转储对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品)`);\n\n const resultA = await this.runWorkerTest('current', 'dump', productCount);\n const resultB = await this.runWorkerTest('baseline', 'dump', productCount);\n\n return { resultA, resultB };\n }\n\n /**\n * 打印对比结果(复用现有的对比结果打印逻辑)\n */\n private printComparisonResults(resultsA: any[], resultsB: any[], testType: string): void {\n // 创建一个临时的 QuoteStateComparisonTest 实例来复用其打印逻辑\n const tempComparison = new QuoteStateComparisonTest(\n () => {\n throw new Error('Not implemented');\n },\n () => {\n throw new Error('Not implemented');\n },\n this.nameA,\n this.nameB,\n );\n\n // 使用私有方法,需要类型断言来访问\n const privateMethod = (tempComparison as any).printComparisonResults;\n if (typeof privateMethod === 'function') {\n privateMethod.call(tempComparison, resultsA, resultsB, testType);\n } else {\n // 如果无法访问私有方法,使用简化版本\n console.log(`\\n${this.nameA} vs ${this.nameB} - ${testType} 对比结果:`);\n for (let i = 0; i < Math.min(resultsA.length, resultsB.length); i++) {\n const a = resultsA[i];\n const b = resultsB[i];\n\n // 检查是否有失败的测试\n const isAFailed = a.success === false;\n const isBFailed = b.success === false;\n\n if (isAFailed || isBFailed) {\n console.log(`\\n产品数量: ${a.productCount || b.productCount}`);\n\n if (isAFailed) {\n console.log(`❌ ${this.nameA} 测试失败: ${a.error || 'Unknown error'}`);\n } else {\n console.log(`${this.nameA}: ${a.avgTime || a.time}ms`);\n }\n\n if (isBFailed) {\n console.log(`❌ ${this.nameB} 测试失败: ${b.error || 'Unknown error'}`);\n } else {\n console.log(`${this.nameB}: ${b.avgTime || b.time}ms`);\n }\n\n // 打印内存使用(即使只有一个实现有数据)\n const memoryUsedA = a.heapUsedDiff;\n const memoryUsedB = b.heapUsedDiff;\n const hasMemoryA = memoryUsedA !== undefined && memoryUsedA !== null && !isNaN(memoryUsedA);\n const hasMemoryB = memoryUsedB !== undefined && memoryUsedB !== null && !isNaN(memoryUsedB);\n\n if (hasMemoryA || hasMemoryB) {\n console.log(`\\n内存使用:`);\n if (hasMemoryA) {\n console.log(`${this.nameA}: ${PerformanceTester.formatBytes(memoryUsedA)}`);\n }\n if (hasMemoryB) {\n console.log(`${this.nameB}: ${PerformanceTester.formatBytes(memoryUsedB)}`);\n }\n }\n\n console.log('-'.repeat(80));\n continue;\n }\n\n console.log(`产品数量 ${a.productCount}: ${a.avgTime || a.time}ms vs ${b.avgTime || b.time}ms`);\n\n // 打印内存使用(即使只有一个实现有数据)\n const memoryUsedA = a.heapUsedDiff;\n const memoryUsedB = b.heapUsedDiff;\n const hasMemoryA = memoryUsedA !== undefined && memoryUsedA !== null && !isNaN(memoryUsedA);\n const hasMemoryB = memoryUsedB !== undefined && memoryUsedB !== null && !isNaN(memoryUsedB);\n\n if (hasMemoryA || hasMemoryB) {\n console.log(`\\n内存使用:`);\n if (hasMemoryA) {\n console.log(`${this.nameA}: ${PerformanceTester.formatBytes(memoryUsedA)}`);\n }\n if (hasMemoryB) {\n console.log(`${this.nameB}: ${PerformanceTester.formatBytes(memoryUsedB)}`);\n }\n\n // 只有当两个实现都有有效内存数据时才进行对比\n if (hasMemoryA && hasMemoryB && memoryUsedA > 0 && memoryUsedB > 0) {\n const memoryRatio = memoryUsedA / memoryUsedB;\n const memoryPercentDiff = ((memoryRatio - 1) * 100).toFixed(2);\n if (memoryRatio > 1) {\n console.log(`${this.nameB} 节省 ${memoryPercentDiff}% 内存`);\n } else {\n console.log(`${this.nameA} 节省 ${(-parseFloat(memoryPercentDiff)).toFixed(2)}% 内存`);\n }\n }\n }\n\n console.log('-'.repeat(80));\n }\n }\n }\n\n /**\n * 运行完整的对比测试套件\n */\n async runComparisonTestSuite(): Promise<void> {\n console.log(`开始子进程隔离内存对比测试: ${this.nameA} vs ${this.nameB}`);\n console.log('注意:每个测试都在独立的子进程中运行,确保内存测试的公平性');\n\n const testScenarios = [\n {\n productCount: 10000,\n label: '10K',\n updateIterations: 1000,\n queryIterations: 10000,\n filterIterations: 1000,\n },\n {\n productCount: 100000,\n label: '100K',\n updateIterations: 100,\n queryIterations: 1000,\n filterIterations: 100,\n },\n {\n productCount: 1000000,\n label: '1M',\n updateIterations: 10,\n queryIterations: 100,\n filterIterations: 10,\n },\n ];\n\n // 初始化测试对比\n console.log('\\n运行初始化测试对比...');\n const initResultsA = [];\n const initResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const { resultA, resultB } = await this.runInitializationTestComparison(scenario.productCount, 3);\n initResultsA.push(resultA);\n initResultsB.push(resultB);\n } catch (error) {\n console.error(`初始化对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(initResultsA, initResultsB, '初始化测试');\n\n // 更新测试对比\n console.log('\\n运行更新测试对比...');\n const updateResultsA = [];\n const updateResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const { resultA, resultB } = await this.runUpdateTestComparison(\n scenario.productCount,\n scenario.updateIterations,\n );\n updateResultsA.push(resultA);\n updateResultsB.push(resultB);\n } catch (error) {\n console.error(`更新对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(updateResultsA, updateResultsB, '更新测试');\n\n // 查询测试对比\n console.log('\\n运行查询测试对比...');\n const queryResultsA = [];\n const queryResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const { resultA, resultB } = await this.runQueryTestComparison(\n scenario.productCount,\n scenario.queryIterations,\n );\n queryResultsA.push(resultA);\n queryResultsB.push(resultB);\n } catch (error) {\n console.error(`查询对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(queryResultsA, queryResultsB, '查询测试');\n\n // 过滤测试对比\n console.log('\\n运行过滤测试对比...');\n const filterResultsA = [];\n const filterResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const { resultA, resultB } = await this.runFilterTestComparison(\n scenario.productCount,\n scenario.filterIterations,\n );\n filterResultsA.push(resultA);\n filterResultsB.push(resultB);\n } catch (error) {\n console.error(`过滤对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(filterResultsA, filterResultsB, '过滤测试');\n\n // 转储测试对比\n console.log('\\n运行转储测试对比...');\n const dumpResultsA = [];\n const dumpResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const { resultA, resultB } = await this.runDumpTestComparison(scenario.productCount);\n dumpResultsA.push(resultA);\n dumpResultsB.push(resultB);\n } catch (error) {\n console.error(`转储对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(dumpResultsA, dumpResultsB, '转储测试');\n\n console.log('\\n子进程隔离内存对比测试完成!');\n }\n\n /**\n * 运行快速对比测试(仅测试小数据量)\n */\n async runQuickComparisonTest(): Promise<void> {\n console.log(`开始快速子进程对比测试: ${this.nameA} vs ${this.nameB}`);\n\n const quickScenarios = [\n {\n productCount: 1000,\n label: '1K',\n updateIterations: 100,\n queryIterations: 1000,\n filterIterations: 100,\n },\n { productCount: 10000, label: '10K', updateIterations: 10, queryIterations: 100, filterIterations: 10 },\n ];\n\n // 初始化测试对比\n console.log('\\n运行初始化测试对比...');\n const initResultsA = [];\n const initResultsB = [];\n for (const scenario of quickScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const { resultA, resultB } = await this.runInitializationTestComparison(scenario.productCount, 2);\n initResultsA.push(resultA);\n initResultsB.push(resultB);\n } catch (error) {\n console.error(`初始化对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(initResultsA, initResultsB, '快速初始化测试');\n\n console.log('\\n快速子进程对比测试完成!');\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"PerformanceTester.js","sourceRoot":"","sources":["../../../src/quote/benchmark/PerformanceTester.ts"],"names":[],"mappings":"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","sourcesContent":["import { performance } from 'perf_hooks';\n\n/**\n * 性能测试工具类\n */\nexport class PerformanceTester {\n /**\n * 测量函数执行时间\n */\n static async measureTime<T>(fn: () => Promise<T> | T): Promise<{ result: T; time: number }> {\n const start = performance.now();\n const result = await fn();\n const end = performance.now();\n return { result, time: end - start };\n }\n\n /**\n * 多次测量函数执行时间,取平均值\n */\n static async measureTimeWithStats<T>(\n fn: () => Promise<T> | T,\n iterations: number = 5,\n ): Promise<{ result: T; avgTime: number; minTime: number; maxTime: number; times: number[] }> {\n const times: number[] = [];\n let finalResult: T | undefined;\n\n for (let i = 0; i < iterations; i++) {\n const start = performance.now();\n const result = await fn();\n const end = performance.now();\n\n if (i === 0) finalResult = result;\n times.push(end - start);\n }\n\n const avgTime = times.reduce((a, b) => a + b, 0) / times.length;\n const minTime = Math.min(...times);\n const maxTime = Math.max(...times);\n\n return {\n result: finalResult!,\n avgTime,\n minTime,\n maxTime,\n times,\n };\n }\n\n /**\n * 尝试触发垃圾回收(如果可用)\n */\n static tryGarbageCollect(): void {\n if (typeof global !== 'undefined' && (global as any).gc) {\n try {\n (global as any).gc();\n } catch (error) {\n // 忽略GC错误\n }\n }\n }\n\n /**\n * 确保在内存测量前清理环境\n */\n static prepareForMemoryMeasurement(): void {\n // 触发GC(如果可用)\n this.tryGarbageCollect();\n\n // 给GC一些时间\n if (typeof setImmediate !== 'undefined') {\n // 使用setImmediate让事件循环有机会处理GC\n return;\n }\n }\n\n /**\n * 获取内存使用情况(在清理后)\n */\n static getMemoryUsage(): NodeJS.MemoryUsage | null {\n this.prepareForMemoryMeasurement();\n if (typeof process !== 'undefined' && process.memoryUsage) {\n return process.memoryUsage();\n }\n return null;\n }\n\n /**\n * 测量内存使用增长\n */\n static async measureMemoryUsage<T>(fn: () => Promise<T> | T): Promise<{\n result: T;\n memoryBefore: NodeJS.MemoryUsage | null;\n memoryAfter: NodeJS.MemoryUsage | null;\n heapUsedDiff: number | null;\n }> {\n // 清理环境并获取初始内存\n this.prepareForMemoryMeasurement();\n const memoryBefore = this.getMemoryUsage();\n\n // 执行函数\n const result = await fn();\n\n // 再次清理环境并获取最终内存\n this.prepareForMemoryMeasurement();\n const memoryAfter = this.getMemoryUsage();\n\n // 计算内存差异\n let heapUsedDiff: number | null = null;\n if (\n memoryBefore &&\n memoryAfter &&\n memoryBefore.heapUsed !== undefined &&\n memoryAfter.heapUsed !== undefined\n ) {\n heapUsedDiff = memoryAfter.heapUsed - memoryBefore.heapUsed;\n }\n\n return {\n result,\n memoryBefore,\n memoryAfter,\n heapUsedDiff,\n };\n }\n\n /**\n * 格式化字节大小\n */\n static formatBytes(bytes: number): string {\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n if (bytes === 0) return '0 Bytes';\n if (isNaN(bytes)) return 'NaN';\n\n const sign = bytes < 0 ? '-' : '';\n const absBytes = Math.abs(bytes);\n\n if (absBytes < 1024) {\n return `${sign}${absBytes} ${sizes[0]}`;\n }\n\n const i = Math.floor(Math.log(absBytes) / Math.log(1024));\n const value = Math.round((absBytes / Math.pow(1024, i)) * 100) / 100;\n return `${sign}${value} ${sizes[i]}`;\n }\n\n /**\n * 格式化时间\n */\n static formatTime(ms: number): string {\n if (ms < 1) return `${ms.toFixed(3)}ms`;\n if (ms < 1000) return `${ms.toFixed(2)}ms`;\n return `${(ms / 1000).toFixed(2)}s`;\n }\n}\n"]}
1
+ {"version":3,"file":"PerformanceTester.js","sourceRoot":"","sources":["../../../src/quote/benchmark/PerformanceTester.ts"],"names":[],"mappings":"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","sourcesContent":["import { performance } from 'perf_hooks';\n\n/**\n * 性能测试工具类\n */\nexport class PerformanceTester {\n /**\n * 测量函数执行时间\n */\n static async measureTime<T>(fn: () => Promise<T> | T): Promise<{ result: T; time: number }> {\n const start = performance.now();\n const result = await fn();\n const end = performance.now();\n return { result, time: end - start };\n }\n\n /**\n * 多次测量函数执行时间,取平均值\n */\n static async measureTimeWithStats<T>(\n fn: () => Promise<T> | T,\n iterations: number = 5,\n ): Promise<{ result: T; avgTime: number; minTime: number; maxTime: number; times: number[] }> {\n const times: number[] = [];\n let finalResult: T | undefined;\n\n for (let i = 0; i < iterations; i++) {\n const start = performance.now();\n const result = await fn();\n const end = performance.now();\n\n if (i === 0) finalResult = result;\n times.push(end - start);\n }\n\n const avgTime = times.reduce((a, b) => a + b, 0) / times.length;\n const minTime = Math.min(...times);\n const maxTime = Math.max(...times);\n\n return {\n result: finalResult!,\n avgTime,\n minTime,\n maxTime,\n times,\n };\n }\n\n /**\n * 尝试触发垃圾回收(如果可用)\n */\n static tryGarbageCollect(): void {\n if (typeof global !== 'undefined' && (global as any).gc) {\n try {\n (global as any).gc();\n } catch (error) {\n // 忽略GC错误\n }\n }\n }\n\n /**\n * 确保在内存测量前清理环境\n */\n static prepareForMemoryMeasurement(): void {\n // 触发GC(如果可用)\n this.tryGarbageCollect();\n\n // 给GC一些时间\n if (typeof setImmediate !== 'undefined') {\n // 使用setImmediate让事件循环有机会处理GC\n return;\n }\n }\n\n /**\n * 获取内存使用情况(在清理后)\n */\n static getMemoryUsage(): NodeJS.MemoryUsage | null {\n this.prepareForMemoryMeasurement();\n if (typeof process !== 'undefined' && process.memoryUsage) {\n return process.memoryUsage();\n }\n return null;\n }\n\n /**\n * 测量内存使用增长\n */\n static async measureMemoryUsage<T>(fn: () => Promise<T> | T): Promise<{\n result: T;\n memoryBefore: NodeJS.MemoryUsage | null;\n memoryAfter: NodeJS.MemoryUsage | null;\n heapUsedDiff: number | null;\n }> {\n // 清理环境并获取初始内存\n this.prepareForMemoryMeasurement();\n const memoryBefore = this.getMemoryUsage();\n\n // 执行函数\n const result = await fn();\n\n // 再次清理环境并获取最终内存\n this.prepareForMemoryMeasurement();\n const memoryAfter = this.getMemoryUsage();\n\n // 计算内存差异\n let heapUsedDiff: number | null = null;\n if (\n memoryBefore &&\n memoryAfter &&\n memoryBefore.heapUsed !== undefined &&\n memoryAfter.heapUsed !== undefined\n ) {\n heapUsedDiff = memoryAfter.heapUsed - memoryBefore.heapUsed;\n }\n\n return {\n result,\n memoryBefore,\n memoryAfter,\n heapUsedDiff,\n };\n }\n\n /**\n * 格式化字节大小\n */\n static formatBytes(bytes: number): string {\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n if (bytes === 0) return '0 Bytes';\n if (isNaN(bytes)) return 'NaN';\n\n const sign = bytes < 0 ? '-' : '';\n const absBytes = Math.abs(bytes);\n\n if (absBytes < 1024) {\n return `${sign}${absBytes} ${sizes[0]}`;\n }\n\n const i = Math.floor(Math.log(absBytes) / Math.log(1024));\n const value = Math.round((absBytes / Math.pow(1024, i)) * 100) / 100;\n return `${sign}${value} ${sizes[i]}`;\n }\n\n /**\n * 格式化时间\n */\n static formatTime(ms: number): string {\n if (ms < 1) return `${ms.toFixed(3)}ms`;\n if (ms < 1000) return `${ms.toFixed(2)}ms`;\n return `${(ms / 1000).toFixed(2)}s`;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"QuoteStateComparisonTest.js","sourceRoot":"","sources":["../../../src/quote/benchmark/QuoteStateComparisonTest.ts"],"names":[],"mappings":"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","sourcesContent":["import { IQuoteState } from '../types';\nimport { PerformanceTester } from './PerformanceTester';\nimport { QuoteStateTestRunner } from './QuoteStateTestRunner';\n\n/**\n * 行情状态对比测试类\n * 用于比较两个不同的 IQuoteState 实现\n */\nexport class QuoteStateComparisonTest {\n private runnerA: QuoteStateTestRunner;\n private runnerB: QuoteStateTestRunner;\n private nameA: string;\n private nameB: string;\n\n constructor(\n createStateA: () => IQuoteState,\n createStateB: () => IQuoteState,\n nameA: string = '实现A',\n nameB: string = '实现B',\n ) {\n this.runnerA = new QuoteStateTestRunner(createStateA);\n this.runnerB = new QuoteStateTestRunner(createStateB);\n this.nameA = nameA;\n this.nameB = nameB;\n }\n\n /**\n * 打印对比结果\n */\n private printComparisonResults(\n resultsA: any[],\n resultsB: any[],\n testType: string,\n key: string = 'time',\n ): void {\n console.log('\\n' + '='.repeat(100));\n console.log(`行情状态性能对比测试 - ${testType}`);\n console.log('='.repeat(100));\n\n console.log(`\\n${this.nameA} vs ${this.nameB} 性能对比:`);\n console.log('-'.repeat(80));\n\n for (let i = 0; i < Math.min(resultsA.length, resultsB.length); i++) {\n const resultA = resultsA[i];\n const resultB = resultsB[i];\n\n // 检查是否有失败的测试\n const isAFailed = resultA.success === false;\n const isBFailed = resultB.success === false;\n\n if (isAFailed || isBFailed) {\n console.log(`\\n产品数量: ${resultA.productCount || resultB.productCount}`);\n\n if (isAFailed) {\n console.log(`❌ ${this.nameA} 测试失败: ${resultA.error || 'Unknown error'}`);\n } else {\n console.log(`${this.nameA}: ${PerformanceTester.formatTime(resultA.avgTime || resultA.time)}`);\n }\n\n if (isBFailed) {\n console.log(`❌ ${this.nameB} 测试失败: ${resultB.error || 'Unknown error'}`);\n } else {\n console.log(`${this.nameB}: ${PerformanceTester.formatTime(resultB.avgTime || resultB.time)}`);\n }\n\n console.log('-'.repeat(80));\n continue;\n }\n\n if (resultA.productCount !== resultB.productCount) {\n console.log(`\\n⚠️ 产品数量不匹配: ${resultA.productCount} vs ${resultB.productCount}`);\n continue;\n }\n\n console.log(`\\n产品数量: ${resultA.productCount.toLocaleString()}`);\n\n // 自动检测使用哪个时间字段\n const timeKey = resultA.avgTime !== undefined ? 'avgTime' : 'time';\n const valueA = resultA[timeKey];\n const valueB = resultB[timeKey];\n\n const timeLabel = timeKey === 'avgTime' ? '平均时间' : '时间';\n console.log(`${this.nameA} (${timeLabel}): ${PerformanceTester.formatTime(valueA)}`);\n console.log(`${this.nameB} (${timeLabel}): ${PerformanceTester.formatTime(valueB)}`);\n\n if (valueA > 0 && valueB > 0) {\n const ratio = valueA / valueB;\n const percentDiff = ((ratio - 1) * 100).toFixed(2);\n if (ratio > 1) {\n console.log(`${this.nameB} 快 ${percentDiff}% (${ratio.toFixed(2)}x)`);\n } else {\n console.log(\n `${this.nameA} 快 ${(-parseFloat(percentDiff)).toFixed(2)}% (${(1 / ratio).toFixed(2)}x)`,\n );\n }\n }\n\n // 处理新的内存数据结构(heapUsedDiff)和旧的数据结构(memoryBefore/memoryAfter)\n let memoryUsedA: number | null = null;\n let memoryUsedB: number | null = null;\n\n if (resultA.heapUsedDiff !== undefined && resultA.heapUsedDiff !== null) {\n memoryUsedA = resultA.heapUsedDiff;\n } else if (resultA.memoryBefore && resultA.memoryAfter) {\n memoryUsedA = resultA.memoryAfter.heapUsed - resultA.memoryBefore.heapUsed;\n }\n\n if (resultB.heapUsedDiff !== undefined && resultB.heapUsedDiff !== null) {\n memoryUsedB = resultB.heapUsedDiff;\n } else if (resultB.memoryBefore && resultB.memoryAfter) {\n memoryUsedB = resultB.memoryAfter.heapUsed - resultB.memoryBefore.heapUsed;\n }\n\n // 打印内存使用(即使只有一个实现有数据)\n const hasMemoryA = memoryUsedA !== null && !isNaN(memoryUsedA);\n const hasMemoryB = memoryUsedB !== null && !isNaN(memoryUsedB);\n\n if (hasMemoryA || hasMemoryB) {\n console.log(`\\n内存使用:`);\n if (hasMemoryA) {\n console.log(`${this.nameA}: ${PerformanceTester.formatBytes(memoryUsedA!)}`);\n }\n if (hasMemoryB) {\n console.log(`${this.nameB}: ${PerformanceTester.formatBytes(memoryUsedB!)}`);\n }\n\n // 只有当两个实现都有有效内存数据时才进行对比\n if (hasMemoryA && hasMemoryB && memoryUsedA! > 0 && memoryUsedB! > 0) {\n const memoryRatio = memoryUsedA! / memoryUsedB!;\n const memoryPercentDiff = ((memoryRatio - 1) * 100).toFixed(2);\n if (memoryRatio > 1) {\n console.log(`${this.nameB} 节省 ${memoryPercentDiff}% 内存`);\n } else {\n console.log(`${this.nameA} 节省 ${(-parseFloat(memoryPercentDiff)).toFixed(2)}% 内存`);\n }\n }\n }\n\n console.log('-'.repeat(80));\n }\n }\n\n /**\n * 运行完整的对比测试套件\n */\n async runComparisonTestSuite(): Promise<void> {\n console.log(`开始行情状态性能对比测试: ${this.nameA} vs ${this.nameB}`);\n\n const testScenarios = [\n {\n productCount: 10000,\n label: '10K',\n updateIterations: 1000,\n queryIterations: 10000,\n filterIterations: 1000,\n },\n {\n productCount: 100000,\n label: '100K',\n updateIterations: 100,\n queryIterations: 1000,\n filterIterations: 100,\n },\n {\n productCount: 1000000,\n label: '1M',\n updateIterations: 10,\n queryIterations: 100,\n filterIterations: 10,\n },\n ];\n\n // 初始化测试对比\n console.log('\\n运行初始化测试对比...');\n const initResultsA = [];\n const initResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n // 使用3次迭代取平均值,减少随机性\n const resultA = await this.runnerA.runInitializationTest(scenario.productCount, 3);\n const resultB = await this.runnerB.runInitializationTest(scenario.productCount, 3);\n initResultsA.push(resultA);\n initResultsB.push(resultB);\n } catch (error) {\n console.error(`初始化对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(initResultsA, initResultsB, '初始化测试');\n\n // 更新测试对比\n console.log('\\n运行更新测试对比...');\n const updateResultsA = [];\n const updateResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const resultA = await this.runnerA.runUpdateTest(scenario.productCount, scenario.updateIterations);\n const resultB = await this.runnerB.runUpdateTest(scenario.productCount, scenario.updateIterations);\n updateResultsA.push(resultA);\n updateResultsB.push(resultB);\n } catch (error) {\n console.error(`更新对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(updateResultsA, updateResultsB, '更新测试');\n\n // 查询测试对比\n console.log('\\n运行查询测试对比...');\n const queryResultsA = [];\n const queryResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const resultA = await this.runnerA.runQueryTest(scenario.productCount, scenario.queryIterations);\n const resultB = await this.runnerB.runQueryTest(scenario.productCount, scenario.queryIterations);\n queryResultsA.push(resultA);\n queryResultsB.push(resultB);\n } catch (error) {\n console.error(`查询对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(queryResultsA, queryResultsB, '查询测试');\n\n // 过滤测试对比\n console.log('\\n运行过滤测试对比...');\n const filterResultsA = [];\n const filterResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const resultA = await this.runnerA.runFilterTest(scenario.productCount, scenario.filterIterations);\n const resultB = await this.runnerB.runFilterTest(scenario.productCount, scenario.filterIterations);\n filterResultsA.push(resultA);\n filterResultsB.push(resultB);\n } catch (error) {\n console.error(`过滤对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(filterResultsA, filterResultsB, '过滤测试');\n\n // 转储测试对比\n console.log('\\n运行转储测试对比...');\n const dumpResultsA = [];\n const dumpResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const resultA = await this.runnerA.runDumpTest(scenario.productCount);\n const resultB = await this.runnerB.runDumpTest(scenario.productCount);\n dumpResultsA.push(resultA);\n dumpResultsB.push(resultB);\n } catch (error) {\n console.error(`转储对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(dumpResultsA, dumpResultsB, '转储测试');\n\n console.log('\\n对比测试完成!');\n }\n\n /**\n * 运行快速对比测试(仅测试小数据量)\n */\n async runQuickComparisonTest(): Promise<void> {\n console.log(`开始快速对比测试: ${this.nameA} vs ${this.nameB}`);\n\n const quickScenarios = [\n {\n productCount: 1000,\n label: '1K',\n updateIterations: 100,\n queryIterations: 1000,\n filterIterations: 100,\n },\n { productCount: 10000, label: '10K', updateIterations: 10, queryIterations: 100, filterIterations: 10 },\n ];\n\n // 初始化测试对比\n console.log('\\n运行初始化测试对比...');\n const initResultsA = [];\n const initResultsB = [];\n for (const scenario of quickScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n // 使用2次迭代取平均值(快速测试)\n const resultA = await this.runnerA.runInitializationTest(scenario.productCount, 2);\n const resultB = await this.runnerB.runInitializationTest(scenario.productCount, 2);\n initResultsA.push(resultA);\n initResultsB.push(resultB);\n } catch (error) {\n console.error(`初始化对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(initResultsA, initResultsB, '快速初始化测试');\n\n console.log('\\n快速对比测试完成!');\n }\n}\n"]}
1
+ {"version":3,"file":"QuoteStateComparisonTest.js","sourceRoot":"","sources":["../../../src/quote/benchmark/QuoteStateComparisonTest.ts"],"names":[],"mappings":"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","sourcesContent":["import { IQuoteState } from '../types';\nimport { PerformanceTester } from './PerformanceTester';\nimport { QuoteStateTestRunner } from './QuoteStateTestRunner';\n\n/**\n * 行情状态对比测试类\n * 用于比较两个不同的 IQuoteState 实现\n */\nexport class QuoteStateComparisonTest {\n private runnerA: QuoteStateTestRunner;\n private runnerB: QuoteStateTestRunner;\n private nameA: string;\n private nameB: string;\n\n constructor(\n createStateA: () => IQuoteState,\n createStateB: () => IQuoteState,\n nameA: string = '实现A',\n nameB: string = '实现B',\n ) {\n this.runnerA = new QuoteStateTestRunner(createStateA);\n this.runnerB = new QuoteStateTestRunner(createStateB);\n this.nameA = nameA;\n this.nameB = nameB;\n }\n\n /**\n * 打印对比结果\n */\n private printComparisonResults(\n resultsA: any[],\n resultsB: any[],\n testType: string,\n key: string = 'time',\n ): void {\n console.log('\\n' + '='.repeat(100));\n console.log(`行情状态性能对比测试 - ${testType}`);\n console.log('='.repeat(100));\n\n console.log(`\\n${this.nameA} vs ${this.nameB} 性能对比:`);\n console.log('-'.repeat(80));\n\n for (let i = 0; i < Math.min(resultsA.length, resultsB.length); i++) {\n const resultA = resultsA[i];\n const resultB = resultsB[i];\n\n // 检查是否有失败的测试\n const isAFailed = resultA.success === false;\n const isBFailed = resultB.success === false;\n\n if (isAFailed || isBFailed) {\n console.log(`\\n产品数量: ${resultA.productCount || resultB.productCount}`);\n\n if (isAFailed) {\n console.log(`❌ ${this.nameA} 测试失败: ${resultA.error || 'Unknown error'}`);\n } else {\n console.log(`${this.nameA}: ${PerformanceTester.formatTime(resultA.avgTime || resultA.time)}`);\n }\n\n if (isBFailed) {\n console.log(`❌ ${this.nameB} 测试失败: ${resultB.error || 'Unknown error'}`);\n } else {\n console.log(`${this.nameB}: ${PerformanceTester.formatTime(resultB.avgTime || resultB.time)}`);\n }\n\n console.log('-'.repeat(80));\n continue;\n }\n\n if (resultA.productCount !== resultB.productCount) {\n console.log(`\\n⚠️ 产品数量不匹配: ${resultA.productCount} vs ${resultB.productCount}`);\n continue;\n }\n\n console.log(`\\n产品数量: ${resultA.productCount.toLocaleString()}`);\n\n // 自动检测使用哪个时间字段\n const timeKey = resultA.avgTime !== undefined ? 'avgTime' : 'time';\n const valueA = resultA[timeKey];\n const valueB = resultB[timeKey];\n\n const timeLabel = timeKey === 'avgTime' ? '平均时间' : '时间';\n console.log(`${this.nameA} (${timeLabel}): ${PerformanceTester.formatTime(valueA)}`);\n console.log(`${this.nameB} (${timeLabel}): ${PerformanceTester.formatTime(valueB)}`);\n\n if (valueA > 0 && valueB > 0) {\n const ratio = valueA / valueB;\n const percentDiff = ((ratio - 1) * 100).toFixed(2);\n if (ratio > 1) {\n console.log(`${this.nameB} 快 ${percentDiff}% (${ratio.toFixed(2)}x)`);\n } else {\n console.log(\n `${this.nameA} 快 ${(-parseFloat(percentDiff)).toFixed(2)}% (${(1 / ratio).toFixed(2)}x)`,\n );\n }\n }\n\n // 处理新的内存数据结构(heapUsedDiff)和旧的数据结构(memoryBefore/memoryAfter)\n let memoryUsedA: number | null = null;\n let memoryUsedB: number | null = null;\n\n if (resultA.heapUsedDiff !== undefined && resultA.heapUsedDiff !== null) {\n memoryUsedA = resultA.heapUsedDiff;\n } else if (resultA.memoryBefore && resultA.memoryAfter) {\n memoryUsedA = resultA.memoryAfter.heapUsed - resultA.memoryBefore.heapUsed;\n }\n\n if (resultB.heapUsedDiff !== undefined && resultB.heapUsedDiff !== null) {\n memoryUsedB = resultB.heapUsedDiff;\n } else if (resultB.memoryBefore && resultB.memoryAfter) {\n memoryUsedB = resultB.memoryAfter.heapUsed - resultB.memoryBefore.heapUsed;\n }\n\n // 打印内存使用(即使只有一个实现有数据)\n const hasMemoryA = memoryUsedA !== null && !isNaN(memoryUsedA);\n const hasMemoryB = memoryUsedB !== null && !isNaN(memoryUsedB);\n\n if (hasMemoryA || hasMemoryB) {\n console.log(`\\n内存使用:`);\n if (hasMemoryA) {\n console.log(`${this.nameA}: ${PerformanceTester.formatBytes(memoryUsedA!)}`);\n }\n if (hasMemoryB) {\n console.log(`${this.nameB}: ${PerformanceTester.formatBytes(memoryUsedB!)}`);\n }\n\n // 只有当两个实现都有有效内存数据时才进行对比\n if (hasMemoryA && hasMemoryB && memoryUsedA! > 0 && memoryUsedB! > 0) {\n const memoryRatio = memoryUsedA! / memoryUsedB!;\n const memoryPercentDiff = ((memoryRatio - 1) * 100).toFixed(2);\n if (memoryRatio > 1) {\n console.log(`${this.nameB} 节省 ${memoryPercentDiff}% 内存`);\n } else {\n console.log(`${this.nameA} 节省 ${(-parseFloat(memoryPercentDiff)).toFixed(2)}% 内存`);\n }\n }\n }\n\n console.log('-'.repeat(80));\n }\n }\n\n /**\n * 运行完整的对比测试套件\n */\n async runComparisonTestSuite(): Promise<void> {\n console.log(`开始行情状态性能对比测试: ${this.nameA} vs ${this.nameB}`);\n\n const testScenarios = [\n {\n productCount: 10000,\n label: '10K',\n updateIterations: 1000,\n queryIterations: 10000,\n filterIterations: 1000,\n },\n {\n productCount: 100000,\n label: '100K',\n updateIterations: 100,\n queryIterations: 1000,\n filterIterations: 100,\n },\n {\n productCount: 1000000,\n label: '1M',\n updateIterations: 10,\n queryIterations: 100,\n filterIterations: 10,\n },\n ];\n\n // 初始化测试对比\n console.log('\\n运行初始化测试对比...');\n const initResultsA = [];\n const initResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n // 使用3次迭代取平均值,减少随机性\n const resultA = await this.runnerA.runInitializationTest(scenario.productCount, 3);\n const resultB = await this.runnerB.runInitializationTest(scenario.productCount, 3);\n initResultsA.push(resultA);\n initResultsB.push(resultB);\n } catch (error) {\n console.error(`初始化对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(initResultsA, initResultsB, '初始化测试');\n\n // 更新测试对比\n console.log('\\n运行更新测试对比...');\n const updateResultsA = [];\n const updateResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const resultA = await this.runnerA.runUpdateTest(scenario.productCount, scenario.updateIterations);\n const resultB = await this.runnerB.runUpdateTest(scenario.productCount, scenario.updateIterations);\n updateResultsA.push(resultA);\n updateResultsB.push(resultB);\n } catch (error) {\n console.error(`更新对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(updateResultsA, updateResultsB, '更新测试');\n\n // 查询测试对比\n console.log('\\n运行查询测试对比...');\n const queryResultsA = [];\n const queryResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const resultA = await this.runnerA.runQueryTest(scenario.productCount, scenario.queryIterations);\n const resultB = await this.runnerB.runQueryTest(scenario.productCount, scenario.queryIterations);\n queryResultsA.push(resultA);\n queryResultsB.push(resultB);\n } catch (error) {\n console.error(`查询对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(queryResultsA, queryResultsB, '查询测试');\n\n // 过滤测试对比\n console.log('\\n运行过滤测试对比...');\n const filterResultsA = [];\n const filterResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const resultA = await this.runnerA.runFilterTest(scenario.productCount, scenario.filterIterations);\n const resultB = await this.runnerB.runFilterTest(scenario.productCount, scenario.filterIterations);\n filterResultsA.push(resultA);\n filterResultsB.push(resultB);\n } catch (error) {\n console.error(`过滤对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(filterResultsA, filterResultsB, '过滤测试');\n\n // 转储测试对比\n console.log('\\n运行转储测试对比...');\n const dumpResultsA = [];\n const dumpResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const resultA = await this.runnerA.runDumpTest(scenario.productCount);\n const resultB = await this.runnerB.runDumpTest(scenario.productCount);\n dumpResultsA.push(resultA);\n dumpResultsB.push(resultB);\n } catch (error) {\n console.error(`转储对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(dumpResultsA, dumpResultsB, '转储测试');\n\n console.log('\\n对比测试完成!');\n }\n\n /**\n * 运行快速对比测试(仅测试小数据量)\n */\n async runQuickComparisonTest(): Promise<void> {\n console.log(`开始快速对比测试: ${this.nameA} vs ${this.nameB}`);\n\n const quickScenarios = [\n {\n productCount: 1000,\n label: '1K',\n updateIterations: 100,\n queryIterations: 1000,\n filterIterations: 100,\n },\n { productCount: 10000, label: '10K', updateIterations: 10, queryIterations: 100, filterIterations: 10 },\n ];\n\n // 初始化测试对比\n console.log('\\n运行初始化测试对比...');\n const initResultsA = [];\n const initResultsB = [];\n for (const scenario of quickScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n // 使用2次迭代取平均值(快速测试)\n const resultA = await this.runnerA.runInitializationTest(scenario.productCount, 2);\n const resultB = await this.runnerB.runInitializationTest(scenario.productCount, 2);\n initResultsA.push(resultA);\n initResultsB.push(resultB);\n } catch (error) {\n console.error(`初始化对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(initResultsA, initResultsB, '快速初始化测试');\n\n console.log('\\n快速对比测试完成!');\n }\n}\n"]}