hackmud-script-manager 0.19.1-c2f3057 → 0.19.1-d57be2a

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/bin/hsm.js CHANGED
@@ -12,7 +12,7 @@ import { pull } from "../pull.js"
12
12
  import { syncMacros } from "../syncMacros.js"
13
13
  import "@samual/lib/readDirectoryWithStats"
14
14
  import "@samual/lib/copyFilePersistent"
15
- const version = "0.19.1-c2f3057",
15
+ const version = "0.19.1-d57be2a",
16
16
  options = new Map(),
17
17
  commands = [],
18
18
  userColours = new Cache(user => {
@@ -316,7 +316,7 @@ switch (commands[0]) {
316
316
  : fileBaseName + ".js"
317
317
  )
318
318
  const golfFile = () =>
319
- readFile(target, { encoding: "utf-8" }).then(async source => {
319
+ readFile(target, { encoding: "utf8" }).then(async source => {
320
320
  const timeStart = performance.now(),
321
321
  { script, warnings } = await processScript(source, {
322
322
  minify: !(options.get("no-minify") || options.get("skip-minify")),
@@ -410,11 +410,12 @@ function logHelp() {
410
410
  )
411
411
  }
412
412
  }
413
- function logInfo({ file, users, minLength, error }, hackmudPath) {
413
+ function logInfo({ path, users, characterCount, error }, hackmudPath) {
414
+ path = relative(".", path)
414
415
  error ?
415
- logError(`error "${chalk.bold(error.message)}" in ${chalk.bold(file)}`)
416
- : console.log(
417
- `pushed ${chalk.bold(file)} to ${users.map(user => chalk.bold(userColours.get(user))).join(", ")} | ${chalk.bold(minLength + "")} chars | ${chalk.bold(resolve(hackmudPath, users[0], "scripts", basename(file, extname(file))) + ".js")}`
416
+ logError(`Error "${chalk.bold(error.message)}" in ${chalk.bold(path)}`)
417
+ : log(
418
+ `Pushed ${chalk.bold(path)} to ${users.map(user => chalk.bold(userColours.get(user))).join(", ")} | ${chalk.bold(characterCount + "")} chars | ${chalk.bold(resolve(hackmudPath, users[0], "scripts", basename(path, extname(path))) + ".js")}`
418
419
  )
419
420
  }
420
421
  function logError(message) {
package/index.d.ts CHANGED
@@ -6,8 +6,8 @@ export { push } from "./push";
6
6
  export { syncMacros } from "./syncMacros";
7
7
  export { watch } from "./watch";
8
8
  export type Info = {
9
- file: string;
9
+ path: string;
10
10
  users: string[];
11
- minLength: number;
11
+ characterCount: number;
12
12
  error: Error | undefined;
13
13
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hackmud-script-manager",
3
- "version": "0.19.1-c2f3057",
3
+ "version": "0.19.1-d57be2a",
4
4
  "description": "Script manager for game hackmud, with minification, TypeScript support, and player script type definition generation.",
5
5
  "keywords": [
6
6
  "api",
package/push.d.ts CHANGED
@@ -21,8 +21,8 @@ export type PushOptions = LaxPartial<{
21
21
  /** Push scripts from a source directory to the hackmud directory.
22
22
  *
23
23
  * Pushes files directly in the source folder to all users
24
- * @param sourceDirectory directory containing source code
25
- * @param hackmudDirectory directory created by hackmud containing user data including scripts
24
+ * @param sourcePath directory containing source code
25
+ * @param hackmudPath directory created by hackmud containing user data including scripts
26
26
  * @param options {@link PushOptions details}
27
27
  * @returns array of info on pushed scripts */
28
- export declare function push(sourceDirectory: string, hackmudDirectory: string, { scripts, onPush, minify, mangleNames, forceQuineCheats }?: PushOptions): Promise<Info[]>;
28
+ export declare function push(sourcePath: string, hackmudPath: string, { scripts, onPush, minify, mangleNames, forceQuineCheats }?: PushOptions): Promise<Info[]>;
package/push.js CHANGED
@@ -1,10 +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"
3
4
  import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
4
5
  import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
5
6
  import { readFile } from "fs/promises"
6
- import { basename, resolve, extname } from "path"
7
- import { supportedExtensions } from "./constants.js"
7
+ import { basename, resolve } from "path"
8
8
  import { processScript } from "./processScript/index.js"
9
9
  import "@babel/generator"
10
10
  import "@babel/parser"
@@ -29,9 +29,9 @@ import "@rollup/plugin-babel"
29
29
  import "@rollup/plugin-commonjs"
30
30
  import "@rollup/plugin-json"
31
31
  import "@rollup/plugin-node-resolve"
32
- import "@samual/lib/assert"
33
32
  import "prettier"
34
33
  import "rollup"
34
+ import "./constants.js"
35
35
  import "./processScript/minify.js"
36
36
  import "@samual/lib/spliceString"
37
37
  import "acorn"
@@ -43,227 +43,96 @@ import "import-meta-resolve"
43
43
  import "./processScript/transform.js"
44
44
  import "@samual/lib/clearObject"
45
45
  async function push(
46
- sourceDirectory,
47
- hackmudDirectory,
46
+ sourcePath,
47
+ hackmudPath,
48
48
  { scripts = ["*.*"], onPush = () => {}, minify = !0, mangleNames = !1, forceQuineCheats } = {}
49
49
  ) {
50
- const scriptNamesByUser = new Cache(_user => new Set()),
51
- wildScriptUsers = new Set(),
52
- wildUserScripts = new Set()
53
- let pushEverything = !1
54
- for (const fullScriptName of scripts) {
55
- const [user, scriptName] = fullScriptName.split(".")
56
- user && "*" != user ?
57
- scriptName && "*" != scriptName ?
58
- scriptNamesByUser.get(user).add(scriptName)
59
- : wildScriptUsers.add(user)
60
- : scriptName && "*" != scriptName ? wildUserScripts.add(scriptName)
61
- : (pushEverything = !0)
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)
62
72
  }
63
- const usersByGlobalScriptsToPush = new Cache(_user => new Set()),
64
- allInfo = [],
65
- scriptNamesAlreadyPushedByUser = new Cache(_user => new Set())
66
- let sourceDirectoryDirents
67
- if (wildUserScripts.size || pushEverything) {
68
- let hackmudDirectoryEntries
69
- ;[hackmudDirectoryEntries, sourceDirectoryDirents] = await Promise.all([
70
- readDirectoryWithStats(hackmudDirectory),
71
- readDirectoryWithStats(sourceDirectory)
72
- ])
73
- const allUsers = new Set([
74
- ...sourceDirectoryDirents.filter(({ stats }) => stats.isDirectory()).map(({ path }) => basename(path)),
75
- ...hackmudDirectoryEntries.filter(({ stats }) => stats.isDirectory()).map(({ name }) => name),
76
- ...hackmudDirectoryEntries
77
- .filter(({ name, stats }) => stats.isFile() && name.endsWith(".key"))
78
- .map(({ name }) => name.slice(0, -4)),
79
- ...scriptNamesByUser.keys(),
80
- ...wildScriptUsers
81
- ])
82
- if (pushEverything) for (const user of allUsers) wildScriptUsers.add(user)
83
- else
84
- for (const user of allUsers) {
85
- const scriptNames = scriptNamesByUser.get(user)
86
- for (const scriptName of wildUserScripts) scriptNames.add(scriptName)
87
- }
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)
88
83
  }
89
84
  await Promise.all(
90
- [...wildScriptUsers].map(async user => {
91
- await readDirectoryWithStats(resolve(sourceDirectory, user)).then(
92
- async entries => {
93
- await Promise.all(
94
- entries.map(async ({ stats, name, path }) => {
95
- if (name.endsWith(".d.ts")) return
96
- const extension = extname(name)
97
- if (stats.isFile() && supportedExtensions.includes(extension)) {
98
- const scriptName = basename(name, extension),
99
- { script: minifiedCode } = await processScript(
100
- await readFile(path, { encoding: "utf-8" }),
101
- {
102
- minify,
103
- scriptUser: user,
104
- scriptName,
105
- filePath: path,
106
- mangleNames,
107
- forceQuineCheats
108
- }
109
- ),
110
- info = {
111
- file: `${user}/${name}`,
112
- users: [user],
113
- minLength: countHackmudCharacters(minifiedCode),
114
- error: void 0
115
- }
116
- scriptNamesAlreadyPushedByUser.get(user).add(scriptName)
117
- allInfo.push(info)
118
- await writeFilePersistent(
119
- resolve(hackmudDirectory, user, `scripts/${scriptName}.js`),
120
- minifiedCode
121
- )
122
- onPush(info)
123
- }
124
- })
125
- )
126
- },
127
- error => {
128
- if ("ENOENT" != error.code) throw error
129
- }
130
- )
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
+ }
131
96
  })
132
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 = []
133
106
  await Promise.all(
134
- [...scriptNamesByUser].map(async ([user, scripts]) => {
135
- wildScriptUsers.has(user) ||
136
- (await Promise.all(
137
- [...scripts].map(async scriptName => {
138
- let code, fileName, filePath
139
- for (const extension of supportedExtensions)
140
- try {
141
- fileName = `${scriptName}${extension}`
142
- code = await readFile((filePath = resolve(sourceDirectory, user, fileName)), {
143
- encoding: "utf-8"
144
- })
145
- break
146
- } catch {}
147
- if (code) {
148
- const { script: minifiedCode } = await processScript(code, {
149
- minify,
150
- scriptUser: user,
151
- scriptName,
152
- filePath,
153
- mangleNames,
154
- forceQuineCheats
155
- }),
156
- info = {
157
- file: `${user}/${fileName}`,
158
- users: [user],
159
- minLength: countHackmudCharacters(minifiedCode),
160
- error: void 0
161
- }
162
- allInfo.push(info)
163
- await writeFilePersistent(
164
- resolve(hackmudDirectory, user, "scripts", scriptName + ".js"),
165
- minifiedCode
166
- )
167
- onPush(info)
168
- } else usersByGlobalScriptsToPush.get(scriptName).add(user)
169
- })
170
- ))
171
- })
172
- )
173
- await (wildScriptUsers.size ?
174
- Promise.all(
175
- (sourceDirectoryDirents || (await readDirectoryWithStats(sourceDirectory))).map(
176
- async ({ path, stats, name }) => {
177
- if (name.endsWith(".d.ts")) return
178
- const extension = extname(name)
179
- if (!stats.isFile() || !supportedExtensions.includes(extension)) return
180
- const scriptName = basename(name, extension),
181
- usersToPushTo = [...wildScriptUsers, ...usersByGlobalScriptsToPush.get(scriptName)].filter(
182
- user => !scriptNamesAlreadyPushedByUser.get(user).has(scriptName)
183
- )
184
- if (!usersToPushTo.length) return
185
- const uniqueID = Math.floor(Math.random() * 2 ** 52)
186
- .toString(36)
187
- .padStart(11, "0"),
188
- { script: minifiedCode } = await processScript(await readFile(path, { encoding: "utf-8" }), {
189
- minify,
190
- scriptUser: !0,
191
- scriptName,
192
- uniqueID,
193
- filePath: path,
194
- mangleNames,
195
- forceQuineCheats
196
- }),
197
- info = {
198
- file: name,
199
- users: usersToPushTo,
200
- minLength: countHackmudCharacters(minifiedCode),
201
- error: void 0
202
- }
203
- await Promise.all(
204
- usersToPushTo.map(user =>
205
- writeFilePersistent(
206
- resolve(hackmudDirectory, user, `scripts/${scriptName}.js`),
207
- minifiedCode
208
- .replace(RegExp(`\\$${uniqueID}\\$SCRIPT_USER\\$`, "g"), user)
209
- .replace(
210
- RegExp(`\\$${uniqueID}\\$FULL_SCRIPT_NAME\\$`, "g"),
211
- `${user}.${scriptName}`
212
- )
213
- )
214
- )
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}`)
215
129
  )
216
- allInfo.push(info)
217
- onPush(info)
218
- }
130
+ )
219
131
  )
220
- )
221
- : Promise.all(
222
- [...usersByGlobalScriptsToPush].map(async ([scriptName, users]) => {
223
- let code, fileName, filePath
224
- for (const extension of supportedExtensions)
225
- try {
226
- fileName = `${scriptName}${extension}`
227
- code = await readFile((filePath = resolve(sourceDirectory, fileName)), { encoding: "utf-8" })
228
- break
229
- } catch {}
230
- if (code) {
231
- const uniqueID = Math.floor(Math.random() * 2 ** 52)
232
- .toString(36)
233
- .padStart(11, "0"),
234
- { script: minifiedCode } = await processScript(code, {
235
- minify,
236
- scriptUser: !0,
237
- scriptName,
238
- uniqueID,
239
- filePath,
240
- mangleNames,
241
- forceQuineCheats
242
- }),
243
- info = {
244
- file: fileName,
245
- users: [...users],
246
- minLength: countHackmudCharacters(minifiedCode),
247
- error: void 0
248
- }
249
- await Promise.all(
250
- [...users].map(user =>
251
- writeFilePersistent(
252
- resolve(hackmudDirectory, user, `scripts/${scriptName}.js`),
253
- minifiedCode
254
- .replace(RegExp(`\\$${uniqueID}\\$SCRIPT_USER\\$`, "g"), user)
255
- .replace(
256
- RegExp(`\\$${uniqueID}\\$FULL_SCRIPT_NAME\\$`, "g"),
257
- `${user}.${scriptName}`
258
- )
259
- )
260
- )
261
- )
262
- allInfo.push(info)
263
- onPush(info)
264
- }
265
- })
266
- ))
132
+ allInfo.push(info)
133
+ onPush(info)
134
+ })
135
+ )
267
136
  return allInfo
268
137
  }
269
138
  export { push }
package/syncMacros.js CHANGED
@@ -12,7 +12,7 @@ async function syncMacros(hackmudPath) {
12
12
  case ".macros":
13
13
  {
14
14
  const [lines, date] = await Promise.all([
15
- readFile(resolve(hackmudPath, file.name), { encoding: "utf-8" }).then(file =>
15
+ readFile(resolve(hackmudPath, file.name), { encoding: "utf8" }).then(file =>
16
16
  file.split("\n")
17
17
  ),
18
18
  stat(resolve(hackmudPath, file.name)).then(({ mtime }) => mtime)
package/watch.js CHANGED
@@ -116,7 +116,7 @@ async function watch(
116
116
  for (const user of scriptNamesToUsers.get(scriptName)) usersToPushToSet.add(user)
117
117
  const usersToPushTo = [...usersToPushToSet].filter(user => !scriptNamesToUsersToSkip.has(user))
118
118
  if (!usersToPushTo.length) {
119
- 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") })
120
120
  return
121
121
  }
122
122
  const uniqueID = Math.floor(Math.random() * 2 ** 52)
@@ -125,7 +125,7 @@ async function watch(
125
125
  filePath = resolve(sourceDirectory, path)
126
126
  let minifiedCode
127
127
  try {
128
- ;({ script: minifiedCode } = await processScript(await readFile(filePath, { encoding: "utf-8" }), {
128
+ ;({ script: minifiedCode } = await processScript(await readFile(filePath, { encoding: "utf8" }), {
129
129
  minify,
130
130
  scriptUser: !0,
131
131
  scriptName,
@@ -136,7 +136,7 @@ async function watch(
136
136
  }))
137
137
  } catch (error) {
138
138
  assert(error instanceof Error, "src/watch.ts:141:36")
139
- onPush?.({ file: path, users: [], minLength: 0, error })
139
+ onPush?.({ path, users: [], characterCount: 0, error })
140
140
  return
141
141
  }
142
142
  await Promise.all(
@@ -150,9 +150,9 @@ async function watch(
150
150
  )
151
151
  )
152
152
  onPush?.({
153
- file: path,
153
+ path,
154
154
  users: usersToPushTo,
155
- minLength: countHackmudCharacters(minifiedCode),
155
+ characterCount: countHackmudCharacters(minifiedCode),
156
156
  error: void 0
157
157
  })
158
158
  return
@@ -168,7 +168,7 @@ async function watch(
168
168
  )
169
169
  return
170
170
  const filePath = resolve(sourceDirectory, path),
171
- sourceCode = await readFile(filePath, { encoding: "utf-8" })
171
+ sourceCode = await readFile(filePath, { encoding: "utf8" })
172
172
  let script
173
173
  try {
174
174
  ;({ script } = await processScript(sourceCode, {
@@ -181,11 +181,11 @@ async function watch(
181
181
  }))
182
182
  } catch (error) {
183
183
  assert(error instanceof Error, "src/watch.ts:177:35")
184
- onPush?.({ file: path, users: [], minLength: 0, error })
184
+ onPush?.({ path, users: [], characterCount: 0, error })
185
185
  return
186
186
  }
187
187
  await writeFilePersistent(resolve(hackmudDirectory, user, "scripts", scriptName + ".js"), script)
188
- onPush?.({ file: path, users: [user], minLength: countHackmudCharacters(script), error: void 0 })
188
+ onPush?.({ path, users: [user], characterCount: countHackmudCharacters(script), error: void 0 })
189
189
  })
190
190
  onReady && watcher.on("ready", onReady)
191
191
  if (!typeDeclarationPath_) return