@typed-assistant/builder 0.0.76 → 0.0.78

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @typed-assistant/builder
2
2
 
3
+ ## 0.0.78
4
+
5
+ ### Patch Changes
6
+
7
+ - Limit log.txt size to 3MB.
8
+
9
+ ## 0.0.77
10
+
11
+ ### Patch Changes
12
+
13
+ - Optimise retrieval of logs.
14
+
3
15
  ## 0.0.76
4
16
 
5
17
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typed-assistant/builder",
3
- "version": "0.0.76",
3
+ "version": "0.0.78",
4
4
  "exports": {
5
5
  "./appProcess": "./src/appProcess.tsx",
6
6
  "./bunInstall": "./src/bunInstall.tsx",
@@ -29,9 +29,9 @@
29
29
  "ts-toolbelt": "^9.6.0",
30
30
  "typescript": "^5.4.0",
31
31
  "@typed-assistant/eslint-config": "0.0.10",
32
- "@typed-assistant/logger": "0.0.21",
33
- "@typed-assistant/utils": "0.0.18",
34
- "@typed-assistant/typescript-config": "0.0.10"
32
+ "@typed-assistant/typescript-config": "0.0.10",
33
+ "@typed-assistant/logger": "0.0.22",
34
+ "@typed-assistant/utils": "0.0.19"
35
35
  },
36
36
  "publishConfig": {
37
37
  "access": "public",
@@ -1,5 +1,9 @@
1
1
  import type { LogSchema } from "@typed-assistant/logger"
2
2
  import { logger } from "@typed-assistant/logger"
3
+ import { levels } from "@typed-assistant/logger/levels"
4
+ import { ONE_MINUTE, ONE_SECOND } from "@typed-assistant/utils/durations"
5
+ import { getSupervisorAPI } from "@typed-assistant/utils/getHassAPI"
6
+ import { withErrorHandling } from "@typed-assistant/utils/withErrorHandling"
3
7
  import Convert from "ansi-to-html"
4
8
  import type { Subprocess } from "bun"
5
9
  import { $ } from "bun"
@@ -10,10 +14,6 @@ import type { List, String } from "ts-toolbelt"
10
14
  import { getAddonInfo } from "./getAddonInfo"
11
15
  import { addKillListener, killSubprocess } from "./killProcess"
12
16
  import { restartAddon } from "./restartAddon"
13
- import { levels } from "@typed-assistant/logger/levels"
14
- import { getSupervisorAPI } from "@typed-assistant/utils/getHassAPI"
15
- import { withErrorHandling } from "@typed-assistant/utils/withErrorHandling"
16
- import { ONE_SECOND } from "@typed-assistant/utils/durations"
17
17
 
18
18
  const indexHtmlFilePath = `${import.meta.dir}/webserver/index.html` as const
19
19
  const cssFile = `${import.meta.dir}/webserver/input.css` as const
@@ -296,6 +296,39 @@ export const startWebappServer = async ({
296
296
  }
297
297
  })
298
298
 
299
+ const watchLogFileSize = async () => {
300
+ if (Bun.file("./log.txt").size > 3 * ONE_MEGABYTE) {
301
+ logger.debug(
302
+ { emoji: "🗑️" },
303
+ "log.txt is too big, deleting old log.txt and renaming new log.txt to old log.txt",
304
+ )
305
+ await $`rm -f ./log.txt.old`.quiet().catch((e) => {
306
+ logger.error(
307
+ { emoji: "🚨", additionalDetails: e.message },
308
+ "Failed to delete old log.txt",
309
+ )
310
+ })
311
+
312
+ await $`cp ./log.txt ./log.txt.old`.catch((e) => {
313
+ logger.error(
314
+ { emoji: "🚨", additionalDetails: e.message },
315
+ "Failed copying log.txt to log.txt.old",
316
+ )
317
+ })
318
+
319
+ await $`cat /dev/null > ./log.txt`.catch((e) => {
320
+ logger.error(
321
+ { emoji: "🚨", additionalDetails: e.message },
322
+ "Failed to empty log.txt",
323
+ )
324
+ })
325
+ }
326
+
327
+ setTimeout(watchLogFileSize, 10 * ONE_MINUTE)
328
+ }
329
+
330
+ watchLogFileSize()
331
+
299
332
  getStats()
300
333
 
301
334
  addKillListener(async () => {
@@ -361,30 +394,31 @@ const getLogsFromFile = async ({
361
394
  try {
362
395
  const limit = Number(limitProp)
363
396
  const offset = Number(offsetProp)
364
- const lines = (await Bun.file("./log.txt").text())
365
- .split("\n")
366
- .map(
367
- (line) =>
368
- (line
369
- ? JSON.parse(line)
370
- : { msg: "Empty line", level: levels.fatal }) as LogSchema,
371
- )
372
- .filter((log) => log.level >= levels[level])
373
- .filter((log) => {
374
- if (!filter) return true
375
- const keywords = filter.toLowerCase().split(" ")
376
- const logText = JSON.stringify(log).toLowerCase()
377
- return keywords.every((keyword) => logText.includes(keyword))
378
- })
379
397
 
380
- const logFile = limit
381
- ? lines.slice(
382
- lines.length - 1 - limit * (offset + 1),
383
- lines.length - 1 - limit * offset,
398
+ const logs = (
399
+ await Bun.file("./log.txt")
400
+ .text()
401
+ .then((text) => text.split("\n"))
402
+ .then((lines) =>
403
+ limit
404
+ ? lines.slice(
405
+ lines.length - 1 - limit * (offset + 1),
406
+ lines.length - 1 - limit * offset,
407
+ )
408
+ : lines,
384
409
  )
385
- : lines
410
+ ).reduce((result, line) => {
411
+ if (filter && !line.toLowerCase().includes(filter.toLowerCase()))
412
+ return result
413
+
414
+ const log = line
415
+ ? JSON.parse(line)
416
+ : { msg: "Empty line", level: levels.fatal }
417
+ if (log.level < levels[level]) return result
418
+ return result.concat(log)
419
+ }, [] as LogSchema[])
386
420
 
387
- return { logs: logFile }
421
+ return { logs }
388
422
  } catch (e) {
389
423
  return {
390
424
  logs: [
@@ -400,6 +434,7 @@ const getLogsFromFile = async ({
400
434
  }
401
435
  }
402
436
  }
437
+ const ONE_MEGABYTE = 1024 * 1024
403
438
 
404
439
  const getBaseName = <const TString extends string>(path: TString) => {
405
440
  return basename(path) as List.Last<String.Split<TString, "/">>