@typed-assistant/builder 0.0.32 → 0.0.34

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typed-assistant/builder",
3
- "version": "0.0.32",
3
+ "version": "0.0.34",
4
4
  "exports": {
5
5
  "./appProcess": "./src/appProcess.tsx",
6
6
  "./bunInstall": "./src/bunInstall.tsx",
@@ -24,10 +24,10 @@
24
24
  "home-assistant-js-websocket": "^8.2.0",
25
25
  "ts-toolbelt": "^9.6.0",
26
26
  "typescript": "^5.3.3",
27
- "@typed-assistant/eslint-config": "0.0.6",
28
- "@typed-assistant/logger": "0.0.10",
29
- "@typed-assistant/typescript-config": "0.0.6",
30
- "@typed-assistant/utils": "0.0.9"
27
+ "@typed-assistant/typescript-config": "0.0.7",
28
+ "@typed-assistant/eslint-config": "0.0.7",
29
+ "@typed-assistant/logger": "0.0.11",
30
+ "@typed-assistant/utils": "0.0.11"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "home-assistant-js-websocket": "^8.2.0"
@@ -1,7 +1,5 @@
1
1
  import { log } from "@typed-assistant/logger"
2
2
  import { generateTypes } from "@typed-assistant/types/generateTypes"
3
- import { getHassAPI, getSupervisorAPI } from "@typed-assistant/utils/getHassAPI"
4
- import { withErrorHandling } from "@typed-assistant/utils/withErrorHandling"
5
3
  import type { Subprocess } from "bun"
6
4
  import { $ } from "bun"
7
5
  import { readFileSync, watch } from "fs"
@@ -16,6 +14,8 @@ import {
16
14
  import { setupGitPoller } from "./setupGitPoller"
17
15
  import { setupWebhook } from "./setupWebhook"
18
16
  import { startWebappServer } from "./setupWebserver"
17
+ import { restartAddon } from "./restartAddon"
18
+ import { getAddonInfo } from "./getAddonInfo"
19
19
 
20
20
  type Processes = Awaited<ReturnType<typeof buildAndStartAppProcess>>
21
21
 
@@ -55,7 +55,19 @@ let multipleProcessesErrorCount = 0
55
55
  let noProcessesErrorCount = 0
56
56
  const checkProcesses = async (
57
57
  entryFile: string,
58
- { onProcessError }: { onProcessError?: (message: string) => void },
58
+ {
59
+ addonUrl,
60
+ onProcessError,
61
+ restartAddonUrl,
62
+ }: {
63
+ addonUrl: string
64
+ onProcessError?: (
65
+ message: string,
66
+ addonUrl: string,
67
+ restartAddonUrl?: string,
68
+ ) => void
69
+ restartAddonUrl: string
70
+ },
59
71
  ) => {
60
72
  const ps = await $`ps -f`.text()
61
73
  const matches = ps.match(new RegExp(`bun .+${entryFile}`, "gmi")) ?? []
@@ -66,7 +78,7 @@ const checkProcesses = async (
66
78
  const message = `🚨 Multiple processes detected. Restarting TypedAssistant addon...`
67
79
  log(message)
68
80
  log(ps)
69
- onProcessError?.(message)
81
+ onProcessError?.(message, addonUrl, restartAddonUrl)
70
82
  // restartAddon()
71
83
  return
72
84
  }
@@ -80,7 +92,7 @@ const checkProcesses = async (
80
92
  const message = `🚨 No processes detected. Restarting TypedAssistant addon...`
81
93
  log(message)
82
94
  log(ps)
83
- onProcessError?.(message)
95
+ onProcessError?.(message, addonUrl, restartAddonUrl)
84
96
  // restartAddon()
85
97
  return
86
98
  }
@@ -88,7 +100,11 @@ const checkProcesses = async (
88
100
  noProcessesErrorCount = 0
89
101
  }
90
102
 
91
- setTimeout(() => checkProcesses(entryFile, { onProcessError }), 5000)
103
+ setTimeout(
104
+ () =>
105
+ checkProcesses(entryFile, { addonUrl, onProcessError, restartAddonUrl }),
106
+ 5000,
107
+ )
92
108
  }
93
109
 
94
110
  export async function setup({
@@ -98,12 +114,14 @@ export async function setup({
98
114
  }: {
99
115
  entryFile: string
100
116
  } & Parameters<typeof generateTypes>[0] &
101
- Parameters<typeof checkProcesses>[1]) {
117
+ Pick<Parameters<typeof checkProcesses>[1], "onProcessError">) {
102
118
  const addonInfo = await getAddonInfo()
103
119
  const basePath = addonInfo?.data.ingress_entry ?? ""
104
120
  const directoryToWatch = join(process.cwd(), "./src")
121
+ const addonUrl = basePath
122
+ const restartAddonUrl = `${basePath}/restart-addon`
105
123
 
106
- checkProcesses(entryFile, { onProcessError })
124
+ checkProcesses(entryFile, { addonUrl, onProcessError, restartAddonUrl })
107
125
  await setupGitSync()
108
126
 
109
127
  let subprocesses = await buildAndStartAppProcess(entryFile, {
@@ -152,28 +170,6 @@ const ig = ignore().add(
152
170
  const shouldIgnoreFileOrFolder = (filename: string) =>
153
171
  ig.ignores(relative(process.cwd(), filename))
154
172
 
155
- const restartAddon = async () => {
156
- if (!process.env.SUPERVISOR_TOKEN) {
157
- log("♻️ Can't restart addon. Exiting...")
158
- process.exit(0)
159
- return
160
- }
161
- log("♻️ Restarting addon...")
162
- await getSupervisorAPI(`/addons/self/restart`, { method: "POST" })
163
- }
164
-
165
- const getAddonInfo = async () => {
166
- log("🔍 Getting addon info...")
167
-
168
- const { data, error } = await withErrorHandling(getSupervisorAPI)<{
169
- data: { ingress_entry: string }
170
- }>("/addons/self/info")
171
-
172
- if (error) log(`🚨 Failed to get addon info: ${error}`)
173
-
174
- return data
175
- }
176
-
177
173
  function setupWatcher({
178
174
  directoryToWatch,
179
175
  entryFile,
@@ -200,6 +196,7 @@ function setupWatcher({
200
196
  if (shouldIgnoreFileOrFolder(filename)) return
201
197
  log(`⚠️ Change to ${filename} detected.`)
202
198
  if (filename.endsWith("process.tsx")) {
199
+ await killSubprocess(getSubprocesses().app)
203
200
  await restartAddon()
204
201
  } else {
205
202
  onSubprocessChange(
@@ -222,3 +219,9 @@ process.on("SIGINT", async () => {
222
219
  await callKillListeners()
223
220
  process.exit(0)
224
221
  })
222
+ process.on("SIGTERM", async () => {
223
+ log("👋 Exiting...")
224
+ await callSoftKillListeners()
225
+ await callKillListeners()
226
+ process.exit(0)
227
+ })
@@ -6,7 +6,15 @@ import { Elysia, t } from "elysia"
6
6
  import { watch } from "fs"
7
7
  import { basename, join } from "path"
8
8
  import type { List, String } from "ts-toolbelt"
9
- import { addKillListener, addSoftKillListener } from "./killProcess"
9
+ import {
10
+ addKillListener,
11
+ addSoftKillListener,
12
+ killSubprocess,
13
+ } from "./killProcess"
14
+ import { restartAddon } from "./restartAddon"
15
+ import { getAddonInfo } from "./getAddonInfo"
16
+ import { withErrorHandling } from "@typed-assistant/utils/withErrorHandling"
17
+ import { getSupervisorAPI } from "@typed-assistant/utils/getHassAPI"
10
18
 
11
19
  const indexHtmlFilePath = `${import.meta.dir}/webserver/index.html` as const
12
20
  const cssFile = `${import.meta.dir}/webserver/input.css` as const
@@ -103,6 +111,18 @@ export const startWebappServer = async ({
103
111
  headers: { "content-type": "text/html" },
104
112
  }),
105
113
  )
114
+ .get("/restart-addon", async () => {
115
+ await killSubprocess(getSubprocesses().app)
116
+ restartAddon()
117
+ })
118
+ .get("/addon-info", async () => {
119
+ const { data, error } = await withErrorHandling(getSupervisorAPI)<{
120
+ data: { ingress_entry: string }
121
+ }>("/addons/self/info")
122
+
123
+ if (error) return error
124
+ return data
125
+ })
106
126
  .get(
107
127
  "/log.txt",
108
128
  async ({ query }) => {