Skip to content

Commit 65b880b

Browse files
committed
feat: populate artifacts cache from the api
1 parent 1a7a912 commit 65b880b

File tree

6 files changed

+102
-41
lines changed

6 files changed

+102
-41
lines changed

src/core/encryption.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import * as importedCrypto from 'crypto'
2+
const crypto = typeof window !== 'undefined' ? window.crypto : importedCrypto
3+
14
const MAX_CHUNK_SIZE = 190 // 2048 bits RSA-OAEP key size, minus padding (256 bits)
25
const CHUNK_SEPARATOR = '|'
36

src/core/storage.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,6 @@ export const liveFlytrapStorage: FlytrapStorage = {
169169
throw errorLog.toString()
170170
}
171171

172-
log.info(
173-
'api-calls',
174-
`[GET] ${FLYTRAP_API_BASE}/api/v1/captures/${captureId} - Received ${data}`,
175-
{ data }
176-
)
177-
178172
const decryptedCapture = await decryptCapture(data, privateKey)
179173

180174
log.info('storage', `Loaded capture ID "${captureId}".`)
@@ -239,12 +233,6 @@ export const liveFlytrapStorage: FlytrapStorage = {
239233
return
240234
}
241235

242-
log.info(
243-
'api-calls',
244-
`[POST] ${FLYTRAP_API_BASE}/api/v1/captures - Payload size ~${stringifiedPayload.length} bytes. Payload:`,
245-
{ payload: newPayload }
246-
)
247-
248236
const { error: captureError } = await post(
249237
`${FLYTRAP_API_BASE}/api/v1/captures`,
250238
stringifiedPayload,

src/core/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export type LogGroup =
1111
| 'identify'
1212
| 'capture'
1313
| 'transform'
14+
| 'cache'
1415

1516
export type FlytrapConfig = {
1617
projectId: string

src/core/util.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getLoadedConfig } from './config'
22
import { FLYTRAP_REPLACE_VALUES, FLYTRAP_UNSERIALIZABLE_VALUE } from './constants'
3+
import { log } from './logging'
34
import { SourceType } from './types'
45

56
/**
@@ -41,6 +42,11 @@ export async function request<DataType = unknown, ErrorType = string>(
4142
body?: BodyInit,
4243
options: RequestInit = {}
4344
): Promise<RequestResponse<DataType, ErrorType>> {
45+
log.info(
46+
'api-calls',
47+
`[🐛 ${method}] ${endpoint} - Size ${formatBytes(JSON.stringify(body).length)}.`,
48+
{ payload: body }
49+
)
4450
try {
4551
const data = await fetch(endpoint, {
4652
...options,
@@ -213,3 +219,9 @@ export function fillUnserializableFlytrapValues(
213219
}
214220
return input
215221
}
222+
223+
export const formatBytes = (bytes: number) => {
224+
if (bytes === 0) return '0 B'
225+
const e = Math.floor(Math.log(bytes) / Math.log(1000))
226+
return `${(bytes / Math.pow(1000, e)).toFixed(2)} ${' KMGTP'.charAt(e)}B`
227+
}

src/transform.ts

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ import { getFileExtension } from './transform/util'
1919
import {
2020
getArtifactsToUpload,
2121
markArtifactAsUploaded,
22-
upsertArtifact
22+
upsertArtifact,
23+
upsertArtifacts
2324
} from './transform/artifacts/cache'
2425
import { Artifact } from './exports'
2526

@@ -228,23 +229,9 @@ export const unpluginOptions: UnpluginOptions = {
228229
}
229230
}
230231

231-
// Cache artifacts
232-
for (let i = 0; i < artifacts.length; i++) {
233-
upsertArtifact(config.projectId, artifacts[i])
234-
}
235-
236-
// Upload artifacts marked as `not-uploaded`
237-
const artifactsToUpload = getArtifactsToUpload(config.projectId)
238-
log.info(
239-
'storage',
240-
`Created ${artifactsToUpload.length} new artifacts to upload. Size: ${
241-
JSON.stringify(artifactsToUpload).length
242-
}`
243-
)
244-
232+
// Upload artifacts
245233
const { data: uploadedBatches, error } = await tryCatch(
246-
// batchedArtifactsUpload(artifacts, config.secretApiKey, config.projectId)
247-
batchedArtifactsUpload(artifactsToUpload, config.secretApiKey, config.projectId)
234+
upsertArtifacts(config.projectId, config.secretApiKey, artifacts)
248235
)
249236
if (error || !uploadedBatches) {
250237
console.error(
@@ -253,18 +240,6 @@ export const unpluginOptions: UnpluginOptions = {
253240
console.error(error)
254241
return
255242
}
256-
257-
for (let i = 0; i < uploadedBatches.length; i++) {
258-
markArtifactAsUploaded(config.projectId, uploadedBatches[i])
259-
}
260-
log.info(
261-
'api-calls',
262-
`Pushed ${artifactsToUpload.length} artifacts in ${
263-
uploadedBatches?.length
264-
} batches to the Flytrap API. Payload size: ~${
265-
JSON.stringify(artifactsToUpload).length
266-
} bytes.`
267-
)
268243
}
269244
}
270245
}

src/transform/artifacts/cache.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import { deepEqual } from 'fast-equals'
44
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs'
55
import { Artifact, CacheFile } from '../../exports'
66
import { cwd } from 'process'
7+
import { formatBytes, get } from '../../core/util'
8+
import { FLYTRAP_API_BASE } from '../../core/config'
9+
import { log } from '../../core/logging'
10+
import { batchedArtifactsUpload } from './batchedArtifactsUpload'
711

812
export const getCacheFilePath = (projectId: string) => {
913
if (process.env.NODE_ENV === 'test') {
@@ -22,6 +26,7 @@ function _createCacheFile(projectId: string): string {
2226
createdTimestamp: Date.now(),
2327
artifactCacheEntries: []
2428
}
29+
log.info('cache', `Creating cache file at path ${cacheFilePath}.`)
2530
writeFileSync(cacheFilePath, JSON.stringify(cache, null, 2))
2631
}
2732
return cacheFilePath
@@ -38,6 +43,65 @@ const _getCacheFile = (projectId: string): CacheFile => {
3843
return JSON.parse(cacheFileContents) as CacheFile
3944
}
4045

46+
const _populateCache = async (projectId: string, secretApiKey: string): Promise<CacheFile> => {
47+
const artifacts = await _fetchUploadedArtifacts(projectId, secretApiKey)
48+
const cache = _getCacheFile(projectId)
49+
for (let i = 0; i < artifacts.length; i++) {
50+
cache.artifactCacheEntries.push({
51+
artifact: artifacts[i],
52+
timestamp: Date.now(),
53+
uploadStatus: 'uploaded'
54+
})
55+
}
56+
_saveCacheFile(projectId, cache)
57+
return cache
58+
}
59+
60+
async function _getArtifactsToUpload(
61+
projectId: string,
62+
secretApiKey: string,
63+
artifacts: Artifact[]
64+
) {
65+
const alreadyUploadedArtifacts = await _fetchUploadedArtifacts(projectId, secretApiKey)
66+
const artifactsToUpload: Artifact[] = []
67+
for (let i = 0; i < artifacts.length; i++) {
68+
const existingArtifactIndex = _indexOfArtifactWithId(
69+
alreadyUploadedArtifacts,
70+
artifacts[i].functionOrCallId
71+
)
72+
if (existingArtifactIndex !== -1) {
73+
// Exists, check if they're the same
74+
if (!deepEqual(alreadyUploadedArtifacts[existingArtifactIndex], artifacts[i])) {
75+
artifactsToUpload.push(artifacts[i])
76+
continue
77+
}
78+
} else {
79+
// Doesn't exist in uploaded artifacts
80+
artifactsToUpload.push(artifacts[i])
81+
}
82+
}
83+
return artifactsToUpload
84+
}
85+
86+
export async function upsertArtifacts(
87+
projectId: string,
88+
secretApiKey: string,
89+
artifacts: Artifact[]
90+
) {
91+
const artifactsToUpload = await _getArtifactsToUpload(projectId, secretApiKey, artifacts)
92+
// Upload artifacts
93+
const uploadedBatches = await batchedArtifactsUpload(artifactsToUpload, secretApiKey, projectId)
94+
log.info(
95+
'storage',
96+
`Pushed ${artifactsToUpload.length} artifacts in ${
97+
uploadedBatches?.length
98+
} batches to the Flytrap API. Payload Size: ${formatBytes(
99+
JSON.stringify(artifactsToUpload).length
100+
)}`
101+
)
102+
return uploadedBatches
103+
}
104+
41105
const _indexOfArtifactWithId = (haystack: Artifact[], functionOrCallId: string) =>
42106
haystack.findIndex((h) => h.functionOrCallId === functionOrCallId)
43107

@@ -96,3 +160,21 @@ export function getArtifactsToUpload(projectId: string) {
96160
.filter((a) => a.uploadStatus !== 'uploaded')
97161
.reduce((acc, curr) => [...acc, curr.artifact], [] as Artifact[])
98162
}
163+
164+
async function _fetchUploadedArtifacts(projectId: string, secretApiKey: string) {
165+
const { data, error } = await get<Artifact[]>(
166+
`${FLYTRAP_API_BASE}/v1/artifacts/${projectId}`,
167+
undefined,
168+
{
169+
headers: new Headers({
170+
Authorization: `Bearer ${secretApiKey}`,
171+
'Content-Type': 'application/json'
172+
})
173+
}
174+
)
175+
if (error || data === null) {
176+
throw error
177+
}
178+
179+
return data
180+
}

0 commit comments

Comments
 (0)