hackmud-script-manager 0.19.1-98e81f8 → 0.19.1-b040eb5

Sign up to get free protection for your applications and to get access to all the features.
package/pull.d.ts CHANGED
@@ -1,9 +1,5 @@
1
- /**
2
- * Copies script from hackmud to local source folder.
3
- *
4
- * @param sourceFolderPath path to folder containing source files
5
- * @param hackmudPath path to hackmud directory
6
- * @param script to pull in `user.name` format
7
- */
8
- export declare const pull: (sourceFolderPath: string, hackmudPath: string, script: string) => Promise<void>;
9
- export default pull;
1
+ /** Copies script from hackmud to local source folder.
2
+ * @param sourceFolderPath path to folder containing source files
3
+ * @param hackmudPath path to hackmud directory
4
+ * @param script to pull in `user.name` format */
5
+ export declare function pull(sourceFolderPath: string, hackmudPath: string, script: string): Promise<void>;
package/pull.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { copyFilePersistent } from "@samual/lib/copyFilePersistent"
2
2
  import { resolve } from "path"
3
- const pull = async (sourceFolderPath, hackmudPath, script) => {
3
+ async function pull(sourceFolderPath, hackmudPath, script) {
4
4
  const [user, name] = script.split(".")
5
5
  if (!user || !name) throw Error('`script` argument must be in "user.name" format')
6
6
  await copyFilePersistent(
@@ -8,4 +8,4 @@ const pull = async (sourceFolderPath, hackmudPath, script) => {
8
8
  resolve(sourceFolderPath, user, name + ".js")
9
9
  )
10
10
  }
11
- export { pull as default, pull }
11
+ export { pull }
package/push.d.ts CHANGED
@@ -1,37 +1,28 @@
1
1
  import type { LaxPartial } from "@samual/lib";
2
2
  import type { Info } from ".";
3
- export type PushOptions = {
4
- /** whether to do the minify step (defaults to `true`) */
5
- minify: boolean;
6
- /** whether to mangle function and class names (defaults to `false`) */
7
- mangleNames: boolean;
8
- /**
9
- * array of scripts in the format `foo.bar`
10
- *
11
- * also accepts wild card (`*`) e.g. `*.bar` or `foo.*`
12
- *
13
- * pushes everything by default (`*.*`)
14
- */
3
+ export type PushOptions = LaxPartial<{
4
+ /** whether to do the minify step (defaults to `true`) */ minify: boolean;
5
+ /** whether to mangle function and class names (defaults to `false`) */ mangleNames: boolean;
6
+ /** array of scripts in the format `foo.bar`
7
+ *
8
+ * also accepts wild card (`*`) e.g. `*.bar` or `foo.*`
9
+ *
10
+ * pushes everything by default (`*.*`) */
15
11
  scripts: string[];
16
- /** callback called on script push */
17
- onPush: (info: Info) => void;
18
- /**
19
- * when set to `true` forces use of quine cheats
20
- *
21
- * when set to `false` forces quine cheats not to be used
22
- *
23
- * when left unset or set to `undefined`, automatically uses or doesn't use quine cheats based on character count
24
- */
12
+ /** callback called on script push */ onPush: (info: Info) => void;
13
+ /** when set to `true` forces use of quine cheats
14
+ *
15
+ * when set to `false` forces quine cheats not to be used
16
+ *
17
+ * when left unset or set to `undefined`, automatically uses or doesn't use quine cheats based on character count
18
+ */
25
19
  forceQuineCheats: boolean;
26
- };
27
- /**
28
- * Push scripts from a source directory to the hackmud directory.
29
- *
30
- * Pushes files directly in the source folder to all users
31
- * @param sourceDirectory directory containing source code
32
- * @param hackmudDirectory directory created by hackmud containing user data including scripts
33
- * @param options {@link PushOptions details}
34
- * @returns array of info on pushed scripts
35
- */
36
- export declare const push: (sourceDirectory: string, hackmudDirectory: string, { scripts, onPush, minify, mangleNames, forceQuineCheats }?: LaxPartial<PushOptions>) => Promise<Info[]>;
37
- export default push;
20
+ }>;
21
+ /** Push scripts from a source directory to the hackmud directory.
22
+ *
23
+ * Pushes files directly in the source folder to all users
24
+ * @param sourcePath directory containing source code
25
+ * @param hackmudPath directory created by hackmud containing user data including scripts
26
+ * @param options {@link PushOptions details}
27
+ * @returns array of info on pushed scripts */
28
+ export declare function push(sourcePath: string, hackmudPath: string, { scripts, onPush, minify, mangleNames, forceQuineCheats }?: PushOptions): Promise<Info[]>;
package/push.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import { Cache } from "@samual/lib/Cache"
2
+ import { ensure, assert } from "@samual/lib/assert"
2
3
  import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
4
+ import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
3
5
  import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
4
- import { readdir, readFile } from "fs/promises"
5
- import { resolve, extname, basename } from "path"
6
- import { supportedExtensions } from "./constants.js"
6
+ import { readFile } from "fs/promises"
7
+ import { basename, resolve } from "path"
7
8
  import { processScript } from "./processScript/index.js"
8
9
  import "@babel/generator"
9
10
  import "@babel/parser"
@@ -28,9 +29,9 @@ import "@rollup/plugin-babel"
28
29
  import "@rollup/plugin-commonjs"
29
30
  import "@rollup/plugin-json"
30
31
  import "@rollup/plugin-node-resolve"
31
- import "@samual/lib/assert"
32
32
  import "prettier"
33
33
  import "rollup"
34
+ import "./constants.js"
34
35
  import "./processScript/minify.js"
35
36
  import "@samual/lib/spliceString"
36
37
  import "acorn"
@@ -41,223 +42,97 @@ import "./processScript/preprocess.js"
41
42
  import "import-meta-resolve"
42
43
  import "./processScript/transform.js"
43
44
  import "@samual/lib/clearObject"
44
- const push = async (
45
- sourceDirectory,
46
- hackmudDirectory,
45
+ async function push(
46
+ sourcePath,
47
+ hackmudPath,
47
48
  { scripts = ["*.*"], onPush = () => {}, minify = !0, mangleNames = !1, forceQuineCheats } = {}
48
- ) => {
49
- const scriptNamesByUser = new Cache(_user => new Set()),
50
- wildScriptUsers = new Set(),
51
- wildUserScripts = new Set()
52
- let pushEverything = !1
53
- for (const fullScriptName of scripts) {
54
- const [user, scriptName] = fullScriptName.split(".")
55
- user && "*" != user ?
56
- scriptName && "*" != scriptName ?
57
- scriptNamesByUser.get(user).add(scriptName)
58
- : wildScriptUsers.add(user)
59
- : scriptName && "*" != scriptName ? wildUserScripts.add(scriptName)
60
- : (pushEverything = !0)
49
+ ) {
50
+ const [sourceFolder, hackmudFolder] = await Promise.all([
51
+ readDirectoryWithStats(sourcePath),
52
+ readDirectoryWithStats(hackmudPath)
53
+ ]),
54
+ sourceFolderFolders = sourceFolder.filter(({ stats }) => stats.isDirectory()),
55
+ allUsers = new Set([
56
+ ...scripts
57
+ .map(scriptName => ensure(scriptName.split(".")[0], "src/push.ts:52:65"))
58
+ .filter(name => "*" != name),
59
+ ...sourceFolderFolders.map(({ name }) => name),
60
+ ...hackmudFolder.filter(({ stats }) => stats.isDirectory()).map(({ name }) => name),
61
+ ...hackmudFolder
62
+ .filter(({ stats, name }) => stats.isFile() && name.endsWith(".key"))
63
+ .map(({ name }) => name.slice(0, -4))
64
+ ]),
65
+ usersToScriptsToPush = new Cache(_user => new Map()),
66
+ scriptNamesToUsers = new Cache(_scriptName => new Set())
67
+ for (const script of scripts) {
68
+ const [user, scriptName] = script.split(".")
69
+ assert(user, "src/push.ts:69:16")
70
+ assert(scriptName, "src/push.ts:70:22")
71
+ "*" == user ? scriptNamesToUsers.set(scriptName, allUsers) : scriptNamesToUsers.get(scriptName).add(user)
61
72
  }
62
- const usersByGlobalScriptsToPush = new Cache(_user => new Set()),
63
- allInfo = [],
64
- scriptNamesAlreadyPushedByUser = new Cache(_user => new Set())
65
- let sourceDirectoryDirents
66
- if (wildUserScripts.size || pushEverything) {
67
- const hackmudDirectoryDirents = await readdir(resolve(hackmudDirectory), { withFileTypes: !0 }),
68
- allUsers = new Set([
69
- ...(sourceDirectoryDirents = await readdir(resolve(sourceDirectory), { withFileTypes: !0 }))
70
- .filter(dirent => dirent.isDirectory())
71
- .map(dirent => dirent.name),
72
- ...hackmudDirectoryDirents.filter(dirent => dirent.isDirectory()).map(dirent => dirent.name),
73
- ...hackmudDirectoryDirents
74
- .filter(dirent => dirent.isFile() && dirent.name.endsWith(".key"))
75
- .map(dirent => dirent.name.slice(0, -4)),
76
- ...scriptNamesByUser.keys(),
77
- ...wildScriptUsers
78
- ])
79
- if (pushEverything) for (const user of allUsers) wildScriptUsers.add(user)
80
- else
81
- for (const user of allUsers) {
82
- const scriptNames = scriptNamesByUser.get(user)
83
- for (const scriptName of wildUserScripts) scriptNames.add(scriptName)
84
- }
73
+ const sourceFolderFiles = sourceFolder.filter(({ stats }) => stats.isFile()),
74
+ wildScriptUsers_ = scriptNamesToUsers.get("*")
75
+ scriptNamesToUsers.delete("*")
76
+ for (const { name, path } of [
77
+ ...sourceFolderFiles.filter(({ name }) => name.endsWith(".js")),
78
+ ...sourceFolderFiles.filter(({ name }) => name.endsWith(".ts"))
79
+ ]) {
80
+ const scriptName = name.slice(0, -3)
81
+ for (const user of [...wildScriptUsers_, ...scriptNamesToUsers.get(scriptName)])
82
+ usersToScriptsToPush.get(user).set(scriptName, path)
85
83
  }
86
84
  await Promise.all(
87
- [...wildScriptUsers].map(async user => {
88
- await readdir(resolve(sourceDirectory, user), { withFileTypes: !0 }).then(
89
- async dirents => {
90
- await Promise.all(
91
- dirents.map(async dirent => {
92
- if (dirent.name.endsWith(".d.ts")) return
93
- const extension = extname(dirent.name)
94
- if (dirent.isFile() && supportedExtensions.includes(extension)) {
95
- const scriptName = basename(dirent.name, extension),
96
- filePath = resolve(sourceDirectory, user, dirent.name),
97
- { script: minifiedCode } = await processScript(
98
- await readFile(filePath, { encoding: "utf-8" }),
99
- {
100
- minify,
101
- scriptUser: user,
102
- scriptName,
103
- filePath,
104
- mangleNames,
105
- forceQuineCheats
106
- }
107
- ),
108
- info = {
109
- file: `${user}/${dirent.name}`,
110
- users: [user],
111
- minLength: countHackmudCharacters(minifiedCode),
112
- error: void 0
113
- }
114
- scriptNamesAlreadyPushedByUser.get(user).add(scriptName)
115
- allInfo.push(info)
116
- await writeFilePersistent(
117
- resolve(hackmudDirectory, user, `scripts/${scriptName}.js`),
118
- minifiedCode
119
- )
120
- onPush(info)
121
- }
122
- })
123
- )
124
- },
125
- error => {
126
- if ("ENOENT" != error.code) throw error
127
- }
128
- )
85
+ sourceFolderFolders.map(async ({ name: user, path }) => {
86
+ const files = (await readDirectoryWithStats(path)).filter(({ stats }) => stats.isFile()),
87
+ scriptFiles = [
88
+ ...files.filter(({ name }) => name.endsWith(".js")),
89
+ ...files.filter(({ name }) => name.endsWith(".ts"))
90
+ ]
91
+ for (const { name, path } of scriptFiles) {
92
+ const scriptName = name.slice(0, -3)
93
+ ;[...wildScriptUsers_, ...scriptNamesToUsers.get(scriptName)].includes(user) &&
94
+ usersToScriptsToPush.get(user).set(scriptName, path)
95
+ }
129
96
  })
130
97
  )
98
+ for (const [scriptName, users] of scriptNamesToUsers)
99
+ for (const user of users)
100
+ if (!usersToScriptsToPush.get(user).has(scriptName))
101
+ throw Error(`Could not find script ${user}.${scriptName} to push`)
102
+ const pathsToUsers = new Cache(_path => new Set())
103
+ for (const [user, scriptsToPush] of usersToScriptsToPush)
104
+ for (const path of scriptsToPush.values()) pathsToUsers.get(path).add(user)
105
+ const allInfo = []
131
106
  await Promise.all(
132
- [...scriptNamesByUser].map(async ([user, scripts]) => {
133
- wildScriptUsers.has(user) ||
134
- (await Promise.all(
135
- [...scripts].map(async scriptName => {
136
- let code, fileName, filePath
137
- for (const extension of supportedExtensions)
138
- try {
139
- fileName = `${scriptName}${extension}`
140
- code = await readFile((filePath = resolve(sourceDirectory, user, fileName)), {
141
- encoding: "utf-8"
142
- })
143
- break
144
- } catch {}
145
- if (code) {
146
- const { script: minifiedCode } = await processScript(code, {
147
- minify,
148
- scriptUser: user,
149
- scriptName,
150
- filePath,
151
- mangleNames,
152
- forceQuineCheats
153
- }),
154
- info = {
155
- file: `${user}/${fileName}`,
156
- users: [user],
157
- minLength: countHackmudCharacters(minifiedCode),
158
- error: void 0
159
- }
160
- allInfo.push(info)
161
- await writeFilePersistent(
162
- resolve(hackmudDirectory, user, "scripts", scriptName + ".js"),
163
- minifiedCode
164
- )
165
- onPush(info)
166
- } else usersByGlobalScriptsToPush.get(scriptName).add(user)
167
- })
168
- ))
169
- })
170
- )
171
- await (wildScriptUsers.size ?
172
- Promise.all(
173
- (sourceDirectoryDirents || (await readdir(resolve(sourceDirectory), { withFileTypes: !0 }))).map(
174
- async dirent => {
175
- if (dirent.name.endsWith(".d.ts")) return
176
- const extension = extname(dirent.name)
177
- if (!dirent.isFile() || !supportedExtensions.includes(extension)) return
178
- const scriptName = basename(dirent.name, extension),
179
- usersToPushTo = [...wildScriptUsers, ...usersByGlobalScriptsToPush.get(scriptName)].filter(
180
- user => !scriptNamesAlreadyPushedByUser.get(user).has(scriptName)
181
- )
182
- if (!usersToPushTo.length) return
183
- const uniqueID = Math.floor(Math.random() * 2 ** 52)
184
- .toString(36)
185
- .padStart(11, "0"),
186
- filePath = resolve(sourceDirectory, dirent.name),
187
- { script: minifiedCode } = await processScript(
188
- await readFile(filePath, { encoding: "utf-8" }),
189
- { minify, scriptUser: !0, scriptName, uniqueID, filePath, mangleNames, forceQuineCheats }
190
- ),
191
- info = {
192
- file: dirent.name,
193
- users: usersToPushTo,
194
- minLength: countHackmudCharacters(minifiedCode),
195
- error: void 0
196
- }
197
- await Promise.all(
198
- usersToPushTo.map(user =>
199
- writeFilePersistent(
200
- resolve(hackmudDirectory, user, `scripts/${scriptName}.js`),
201
- minifiedCode
202
- .replace(RegExp(`\\$${uniqueID}\\$SCRIPT_USER\\$`, "g"), user)
203
- .replace(
204
- RegExp(`\\$${uniqueID}\\$FULL_SCRIPT_NAME\\$`, "g"),
205
- `${user}.${scriptName}`
206
- )
207
- )
208
- )
107
+ [...pathsToUsers].map(async ([path, [...users]]) => {
108
+ const scriptName = basename(path.slice(0, -3)),
109
+ uniqueID = Math.floor(Math.random() * 2 ** 52)
110
+ .toString(36)
111
+ .padStart(11, "0"),
112
+ { script: minifiedCode } = await processScript(await readFile(path, { encoding: "utf8" }), {
113
+ minify,
114
+ scriptUser: !0,
115
+ scriptName,
116
+ uniqueID,
117
+ filePath: path,
118
+ mangleNames,
119
+ forceQuineCheats
120
+ }),
121
+ info = { path, users, characterCount: countHackmudCharacters(minifiedCode), error: void 0 }
122
+ await Promise.all(
123
+ users.map(user =>
124
+ writeFilePersistent(
125
+ resolve(hackmudPath, user, `scripts/${scriptName}.js`),
126
+ minifiedCode
127
+ .replace(RegExp(`\\$${uniqueID}\\$SCRIPT_USER\\$`, "g"), user)
128
+ .replace(RegExp(`\\$${uniqueID}\\$FULL_SCRIPT_NAME\\$`, "g"), `${user}.${scriptName}`)
209
129
  )
210
- allInfo.push(info)
211
- onPush(info)
212
- }
130
+ )
213
131
  )
214
- )
215
- : Promise.all(
216
- [...usersByGlobalScriptsToPush].map(async ([scriptName, users]) => {
217
- let code, fileName, filePath
218
- for (const extension of supportedExtensions)
219
- try {
220
- fileName = `${scriptName}${extension}`
221
- code = await readFile((filePath = resolve(sourceDirectory, fileName)), { encoding: "utf-8" })
222
- break
223
- } catch {}
224
- if (code) {
225
- const uniqueID = Math.floor(Math.random() * 2 ** 52)
226
- .toString(36)
227
- .padStart(11, "0"),
228
- { script: minifiedCode } = await processScript(code, {
229
- minify,
230
- scriptUser: !0,
231
- scriptName,
232
- uniqueID,
233
- filePath,
234
- mangleNames,
235
- forceQuineCheats
236
- }),
237
- info = {
238
- file: fileName,
239
- users: [...users],
240
- minLength: countHackmudCharacters(minifiedCode),
241
- error: void 0
242
- }
243
- await Promise.all(
244
- [...users].map(user =>
245
- writeFilePersistent(
246
- resolve(hackmudDirectory, user, `scripts/${scriptName}.js`),
247
- minifiedCode
248
- .replace(RegExp(`\\$${uniqueID}\\$SCRIPT_USER\\$`, "g"), user)
249
- .replace(
250
- RegExp(`\\$${uniqueID}\\$FULL_SCRIPT_NAME\\$`, "g"),
251
- `${user}.${scriptName}`
252
- )
253
- )
254
- )
255
- )
256
- allInfo.push(info)
257
- onPush(info)
258
- }
259
- })
260
- ))
132
+ allInfo.push(info)
133
+ onPush(info)
134
+ })
135
+ )
261
136
  return allInfo
262
137
  }
263
- export { push as default, push }
138
+ export { push }
package/syncMacros.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- export declare const syncMacros: (hackmudPath: string) => Promise<{
1
+ export declare function syncMacros(hackmudPath: string): Promise<{
2
2
  macrosSynced: number;
3
3
  usersSynced: number;
4
4
  }>;
5
- export default syncMacros;
package/syncMacros.js CHANGED
@@ -1,17 +1,18 @@
1
- import { readdir, readFile, stat, writeFile } from "fs/promises"
1
+ import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
2
+ import { readFile, stat, writeFile } from "fs/promises"
2
3
  import { extname, basename, resolve } from "path"
3
- const syncMacros = async hackmudPath => {
4
- const files = await readdir(hackmudPath, { withFileTypes: !0 }),
4
+ async function syncMacros(hackmudPath) {
5
+ const files = await readDirectoryWithStats(hackmudPath),
5
6
  macros = new Map(),
6
7
  users = []
7
8
  await Promise.all(
8
9
  files.map(async file => {
9
- if (file.isFile())
10
+ if (file.stats.isFile())
10
11
  switch (extname(file.name)) {
11
12
  case ".macros":
12
13
  {
13
14
  const [lines, date] = await Promise.all([
14
- readFile(resolve(hackmudPath, file.name), { encoding: "utf-8" }).then(file =>
15
+ readFile(resolve(hackmudPath, file.name), { encoding: "utf8" }).then(file =>
15
16
  file.split("\n")
16
17
  ),
17
18
  stat(resolve(hackmudPath, file.name)).then(({ mtime }) => mtime)
@@ -39,4 +40,4 @@ const syncMacros = async hackmudPath => {
39
40
  for (const user of users) writeFile(resolve(hackmudPath, user + ".macros"), macroFile)
40
41
  return { macrosSynced, usersSynced: users.length }
41
42
  }
42
- export { syncMacros as default, syncMacros }
43
+ export { syncMacros }
package/watch.d.ts CHANGED
@@ -1,20 +1,14 @@
1
1
  import type { LaxPartial } from "@samual/lib";
2
2
  import type { PushOptions } from "./push";
3
- export type WatchOptions = PushOptions & {
4
- /**
5
- * if provided, will write typescript type declarations for all the scripts on every change detected
6
- *
7
- * writing the type declarations enables interscript type checking and autocompletetes for the args
8
- */
3
+ export type WatchOptions = PushOptions & LaxPartial<{
4
+ /** if provided, will write typescript type declarations for all the scripts on every change detected
5
+ *
6
+ * writing the type declarations enables interscript type checking and autocompletetes for the args */
9
7
  typeDeclarationPath: string;
10
8
  onReady: () => void;
11
- };
12
- /**
13
- * Watches target file or folder for updates and builds and pushes updated file.
14
- *
15
- * @param sourceDirectory path to folder containing source files
16
- * @param hackmudDirectory path to hackmud directory
17
- * @param options {@link WatchOptions details} and {@link PushOptions more details}
18
- */
19
- export declare const watch: (sourceDirectory: string, hackmudDirectory: string, { scripts, onPush, minify, mangleNames, typeDeclarationPath: typeDeclarationPath_, onReady, forceQuineCheats }?: LaxPartial<WatchOptions>) => Promise<void>;
20
- export default watch;
9
+ }>;
10
+ /** Watches target file or folder for updates and builds and pushes updated file.
11
+ * @param sourceDirectory path to folder containing source files
12
+ * @param hackmudDirectory path to hackmud directory
13
+ * @param options {@link WatchOptions details} and {@link PushOptions more details} */
14
+ export declare function watch(sourceDirectory: string, hackmudDirectory: string, { scripts, onPush, minify, mangleNames, typeDeclarationPath: typeDeclarationPath_, onReady, forceQuineCheats }?: WatchOptions): Promise<void>;
package/watch.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import { Cache } from "@samual/lib/Cache"
2
2
  import { assert } from "@samual/lib/assert"
3
3
  import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
4
+ import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
4
5
  import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
5
6
  import { watch as watch$1 } from "chokidar"
6
- import { readdir, readFile, writeFile } from "fs/promises"
7
+ import { readFile, writeFile } from "fs/promises"
7
8
  import { extname, basename, resolve } from "path"
8
9
  import { supportedExtensions } from "./constants.js"
9
10
  import { generateTypeDeclaration } from "./generateTypeDeclaration.js"
@@ -43,7 +44,7 @@ import "./processScript/preprocess.js"
43
44
  import "import-meta-resolve"
44
45
  import "./processScript/transform.js"
45
46
  import "@samual/lib/clearObject"
46
- const watch = async (
47
+ async function watch(
47
48
  sourceDirectory,
48
49
  hackmudDirectory,
49
50
  {
@@ -55,7 +56,7 @@ const watch = async (
55
56
  onReady,
56
57
  forceQuineCheats
57
58
  } = {}
58
- ) => {
59
+ ) {
59
60
  if (!scripts.length) throw Error("scripts option was an empty array")
60
61
  const scriptNamesToUsers = new Cache(_scriptName => new Set()),
61
62
  wildScriptUsers = new Set(),
@@ -91,33 +92,31 @@ const watch = async (
91
92
  return
92
93
  const scriptNamesToUsersToSkip = new Cache(_scriptName => [])
93
94
  await Promise.all(
94
- (await readdir(sourceDirectory, { withFileTypes: !0 })).map(async dirent => {
95
- if (dirent.isDirectory())
96
- for (const file of await readdir(resolve(sourceDirectory, dirent.name), {
97
- withFileTypes: !0
98
- })) {
99
- if (!file.isFile()) continue
100
- const fileExtension = extname(file.name)
101
- supportedExtensions.includes(fileExtension) &&
102
- scriptNamesToUsersToSkip.get(basename(file.name, fileExtension)).push(dirent.name)
103
- }
95
+ (await readDirectoryWithStats(sourceDirectory)).map(async ({ stats, name, path }) => {
96
+ if (stats.isDirectory())
97
+ for (const child of await readDirectoryWithStats(path))
98
+ if (child.stats.isFile()) {
99
+ const fileExtension = extname(child.name)
100
+ supportedExtensions.includes(fileExtension) &&
101
+ scriptNamesToUsersToSkip.get(basename(child.name, fileExtension)).push(name)
102
+ }
104
103
  })
105
104
  )
106
105
  const usersToPushToSet = new Set()
107
106
  if (pushEverything || wildUserScripts.has(scriptName)) {
108
- for (const dirent of await readdir(resolve(sourceDirectory), { withFileTypes: !0 }))
109
- dirent.isDirectory() && usersToPushToSet.add(dirent.name)
110
- for (const dirent of await readdir(resolve(hackmudDirectory), { withFileTypes: !0 }))
111
- dirent.isDirectory() ?
112
- usersToPushToSet.add(dirent.name)
113
- : dirent.isFile() && dirent.name.endsWith(".key") && usersToPushToSet.add(dirent.name.slice(0, -4))
107
+ for (const { stats, name } of await readDirectoryWithStats(sourceDirectory))
108
+ stats.isDirectory() && usersToPushToSet.add(name)
109
+ for (const { stats, name } of await readDirectoryWithStats(hackmudDirectory))
110
+ stats.isDirectory() ?
111
+ usersToPushToSet.add(name)
112
+ : stats.isFile() && name.endsWith(".key") && usersToPushToSet.add(name.slice(0, -4))
114
113
  for (const users of scriptNamesToUsers.values()) for (const user of users) usersToPushToSet.add(user)
115
114
  }
116
115
  for (const user of wildScriptUsers) usersToPushToSet.add(user)
117
116
  for (const user of scriptNamesToUsers.get(scriptName)) usersToPushToSet.add(user)
118
117
  const usersToPushTo = [...usersToPushToSet].filter(user => !scriptNamesToUsersToSkip.has(user))
119
118
  if (!usersToPushTo.length) {
120
- onPush?.({ file: path, users: [], minLength: 0, error: Error("no users to push to") })
119
+ onPush?.({ path, users: [], characterCount: 0, error: Error("no users to push to") })
121
120
  return
122
121
  }
123
122
  const uniqueID = Math.floor(Math.random() * 2 ** 52)
@@ -126,7 +125,7 @@ const watch = async (
126
125
  filePath = resolve(sourceDirectory, path)
127
126
  let minifiedCode
128
127
  try {
129
- ;({ script: minifiedCode } = await processScript(await readFile(filePath, { encoding: "utf-8" }), {
128
+ ;({ script: minifiedCode } = await processScript(await readFile(filePath, { encoding: "utf8" }), {
130
129
  minify,
131
130
  scriptUser: !0,
132
131
  scriptName,
@@ -136,8 +135,8 @@ const watch = async (
136
135
  forceQuineCheats
137
136
  }))
138
137
  } catch (error) {
139
- assert(error instanceof Error)
140
- onPush?.({ file: path, users: [], minLength: 0, error })
138
+ assert(error instanceof Error, "src/watch.ts:141:36")
139
+ onPush?.({ path, users: [], characterCount: 0, error })
141
140
  return
142
141
  }
143
142
  await Promise.all(
@@ -151,9 +150,9 @@ const watch = async (
151
150
  )
152
151
  )
153
152
  onPush?.({
154
- file: path,
153
+ path,
155
154
  users: usersToPushTo,
156
- minLength: countHackmudCharacters(minifiedCode),
155
+ characterCount: countHackmudCharacters(minifiedCode),
157
156
  error: void 0
158
157
  })
159
158
  return
@@ -169,7 +168,7 @@ const watch = async (
169
168
  )
170
169
  return
171
170
  const filePath = resolve(sourceDirectory, path),
172
- sourceCode = await readFile(filePath, { encoding: "utf-8" })
171
+ sourceCode = await readFile(filePath, { encoding: "utf8" })
173
172
  let script
174
173
  try {
175
174
  ;({ script } = await processScript(sourceCode, {
@@ -181,12 +180,12 @@ const watch = async (
181
180
  forceQuineCheats
182
181
  }))
183
182
  } catch (error) {
184
- assert(error instanceof Error)
185
- onPush?.({ file: path, users: [], minLength: 0, error })
183
+ assert(error instanceof Error, "src/watch.ts:177:35")
184
+ onPush?.({ path, users: [], characterCount: 0, error })
186
185
  return
187
186
  }
188
187
  await writeFilePersistent(resolve(hackmudDirectory, user, "scripts", scriptName + ".js"), script)
189
- onPush?.({ file: path, users: [user], minLength: countHackmudCharacters(script), error: void 0 })
188
+ onPush?.({ path, users: [user], characterCount: countHackmudCharacters(script), error: void 0 })
190
189
  })
191
190
  onReady && watcher.on("ready", onReady)
192
191
  if (!typeDeclarationPath_) return
@@ -196,7 +195,7 @@ const watch = async (
196
195
  try {
197
196
  await writeFile(typeDeclarationPath, typeDeclaration)
198
197
  } catch (error) {
199
- assert(error instanceof Error)
198
+ assert(error instanceof Error, "src/watch.ts:210:35")
200
199
  if ("EISDIR" != error.code) throw error
201
200
  typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
202
201
  await writeFile(typeDeclarationPath, typeDeclaration)
@@ -206,4 +205,4 @@ const watch = async (
206
205
  watcher.on("add", writeTypeDeclaration)
207
206
  watcher.on("unlink", writeTypeDeclaration)
208
207
  }
209
- export { watch as default, watch }
208
+ export { watch }