hackmud-script-manager 0.19.1-b3a477d → 0.19.1-b80922d

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-b3a477d",
15
+ const version = "0.19.1-b80922d",
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: "utf8" }).then(async source => {
319
+ readFile(target, { encoding: "utf-8" }).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,12 +410,11 @@ function logHelp() {
410
410
  )
411
411
  }
412
412
  }
413
- function logInfo({ path, users, characterCount, error }, hackmudPath) {
414
- path = relative(".", path)
413
+ function logInfo({ file, users, minLength, error }, hackmudPath) {
415
414
  error ?
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")}`
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")}`
419
418
  )
420
419
  }
421
420
  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
- path: string;
9
+ file: string;
10
10
  users: string[];
11
- characterCount: number;
11
+ minLength: 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-b3a477d",
3
+ "version": "0.19.1-b80922d",
4
4
  "description": "Script manager for game hackmud, with minification, TypeScript support, and player script type definition generation.",
5
5
  "keywords": [
6
6
  "api",
@@ -51,18 +51,13 @@ function transform(file, sourceCode, { uniqueID = "00000000000", scriptUser, scr
51
51
  referencePath.replaceWith(t.stringLiteral(1 == scriptName ? `$${uniqueID}$SCRIPT_NAME$` : scriptName))
52
52
  if (program.scope.hasGlobal("_FULL_SCRIPT_NAME"))
53
53
  for (const referencePath of getReferencePathsToGlobal("_FULL_SCRIPT_NAME", program))
54
- if (1 == scriptUser || 1 == scriptName)
55
- referencePath.replaceWith(t.stringLiteral(`$${uniqueID}$FULL_SCRIPT_NAME$`))
56
- else if (null == scriptUser) {
57
- uniqueIdScriptUserNeeded = !0
58
- referencePath.replaceWith(
59
- t.binaryExpression(
60
- "+",
61
- t.identifier(`_${uniqueID}_SCRIPT_USER_`),
62
- t.stringLiteral("." + scriptName)
63
- )
54
+ referencePath.replaceWith(
55
+ t.stringLiteral(
56
+ 1 == scriptUser || 1 == scriptName ?
57
+ `$${uniqueID}$FULL_SCRIPT_NAME$`
58
+ : `${scriptUser}.${scriptName}`
64
59
  )
65
- } else referencePath.replaceWith(t.stringLiteral(`${scriptUser}.${scriptName}`))
60
+ )
66
61
  let functionDotPrototypeIsReferencedMultipleTimes = !1
67
62
  if (program.scope.hasGlobal("Function")) {
68
63
  const FunctionReferencePaths = getReferencePathsToGlobal("Function", program)
@@ -70,30 +65,30 @@ function transform(file, sourceCode, { uniqueID = "00000000000", scriptUser, scr
70
65
  const referencePath = FunctionReferencePaths[0]
71
66
  assert(
72
67
  "MemberExpression" == referencePath.parent.type,
73
- "src/processScript/transform.ts:105:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
68
+ "src/processScript/transform.ts:98:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
74
69
  )
75
70
  assert(
76
71
  "Identifier" == referencePath.parent.property.type,
77
- "src/processScript/transform.ts:110:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
72
+ "src/processScript/transform.ts:103:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
78
73
  )
79
74
  assert(
80
75
  "prototype" == referencePath.parent.property.name,
81
- "src/processScript/transform.ts:115:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
76
+ "src/processScript/transform.ts:108:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
82
77
  )
83
78
  referencePath.parentPath.replaceWith(createGetFunctionPrototypeNode())
84
79
  } else {
85
80
  for (const referencePath of FunctionReferencePaths) {
86
81
  assert(
87
82
  "MemberExpression" == referencePath.parent.type,
88
- "src/processScript/transform.ts:123:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
83
+ "src/processScript/transform.ts:116:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
89
84
  )
90
85
  assert(
91
86
  "Identifier" == referencePath.parent.property.type,
92
- "src/processScript/transform.ts:128:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
87
+ "src/processScript/transform.ts:121:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
93
88
  )
94
89
  assert(
95
90
  "prototype" == referencePath.parent.property.name,
96
- "src/processScript/transform.ts:133:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
91
+ "src/processScript/transform.ts:126:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
97
92
  )
98
93
  functionDotPrototypeIsReferencedMultipleTimes = !0
99
94
  referencePath.parentPath.replaceWith(t.identifier(`_${uniqueID}_FUNCTION_DOT_PROTOTYPE_`))
@@ -129,12 +124,12 @@ function transform(file, sourceCode, { uniqueID = "00000000000", scriptUser, scr
129
124
  const neededDbMethodLets = new Set()
130
125
  if (program.scope.hasGlobal("$db"))
131
126
  for (const referencePath of getReferencePathsToGlobal("$db", program)) {
132
- assert("MemberExpression" == referencePath.parentPath.node.type, "src/processScript/transform.ts:187:69")
133
- assert("Identifier" == referencePath.parentPath.node.property.type, "src/processScript/transform.ts:188:72")
127
+ assert("MemberExpression" == referencePath.parentPath.node.type, "src/processScript/transform.ts:180:69")
128
+ assert("Identifier" == referencePath.parentPath.node.property.type, "src/processScript/transform.ts:181:72")
134
129
  const databaseOpMethodName = referencePath.parentPath.node.property.name
135
130
  assert(
136
131
  validDBMethods.includes(databaseOpMethodName),
137
- `src/processScript/transform.ts:194:8 invalid db method "${databaseOpMethodName}", valid db methods are "${validDBMethods.join('", "')}"`
132
+ `src/processScript/transform.ts:187:8 invalid db method "${databaseOpMethodName}", valid db methods are "${validDBMethods.join('", "')}"`
138
133
  )
139
134
  if ("CallExpression" == referencePath.parentPath.parentPath?.type)
140
135
  referencePath.parentPath.replaceWith(t.identifier(`$${uniqueID}$DB$${databaseOpMethodName}$`))
@@ -167,7 +162,7 @@ function transform(file, sourceCode, { uniqueID = "00000000000", scriptUser, scr
167
162
  if (program.scope.hasGlobal("Object"))
168
163
  for (const referencePath of getReferencePathsToGlobal("Object", program))
169
164
  if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
170
- assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:241:64")
165
+ assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:234:64")
171
166
  if ("getPrototypeOf" == referencePath.parent.property.name) {
172
167
  referencePath.parentPath.replaceWith(t.identifier(`_${uniqueID}_GET_PROTOTYPE_OF_`))
173
168
  needGetPrototypeOf = !0
@@ -177,7 +172,7 @@ function transform(file, sourceCode, { uniqueID = "00000000000", scriptUser, scr
177
172
  if (program.scope.hasGlobal("console"))
178
173
  for (const referencePath of getReferencePathsToGlobal("console", program))
179
174
  if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
180
- assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:256:64")
175
+ assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:249:64")
181
176
  referencePath.parentPath.replaceWith(
182
177
  t.identifier(`_${uniqueID}_CONSOLE_METHOD_${referencePath.parent.property.name}_`)
183
178
  )
@@ -185,13 +180,13 @@ function transform(file, sourceCode, { uniqueID = "00000000000", scriptUser, scr
185
180
  }
186
181
  const lastStatement = program.node.body.at(-1)
187
182
  let exportDefaultName
188
- assert(lastStatement, "src/processScript/transform.ts:270:27 program is empty")
183
+ assert(lastStatement, "src/processScript/transform.ts:263:27 program is empty")
189
184
  if ("ExportNamedDeclaration" == lastStatement.type) {
190
185
  program.node.body.pop()
191
186
  for (const specifier of lastStatement.specifiers) {
192
187
  assert(
193
188
  "ExportSpecifier" == specifier.type,
194
- `src/processScript/transform.ts:276:51 ${specifier.type} is currently unsupported`
189
+ `src/processScript/transform.ts:269:51 ${specifier.type} is currently unsupported`
195
190
  )
196
191
  const exportedName =
197
192
  "Identifier" == specifier.exported.type ? specifier.exported.name : specifier.exported.value
@@ -314,11 +309,11 @@ function transform(file, sourceCode, { uniqueID = "00000000000", scriptUser, scr
314
309
  let hoistedGlobalBlockFunctions = 0
315
310
  for (const [globalBlockIndex, globalBlockStatement] of [...globalBlock.body.entries()].reverse())
316
311
  if ("VariableDeclaration" == globalBlockStatement.type) {
317
- assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:410:59")
312
+ assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:403:59")
318
313
  const declarator = globalBlockStatement.declarations[0]
319
314
  assert(
320
315
  "Identifier" == declarator.id.type,
321
- `src/processScript/transform.ts:414:51 declarator.id.type was "${declarator.id.type}"`
316
+ `src/processScript/transform.ts:407:51 declarator.id.type was "${declarator.id.type}"`
322
317
  )
323
318
  program.scope.crawl()
324
319
  if (program.scope.hasGlobal(declarator.id.name)) {
@@ -333,9 +328,9 @@ function transform(file, sourceCode, { uniqueID = "00000000000", scriptUser, scr
333
328
  Object.keys(program.scope.globals).some(global => globalBlockVariables.has(global))
334
329
  ) {
335
330
  const binding = program.scope.getBinding(declarator.id.name)
336
- assert(binding, "src/processScript/transform.ts:433:23")
331
+ assert(binding, "src/processScript/transform.ts:426:23")
337
332
  for (const referencePath of binding.referencePaths) {
338
- assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:436:56")
333
+ assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:429:56")
339
334
  referencePath.replaceWith(
340
335
  t.memberExpression(
341
336
  t.identifier(`$${uniqueID}$GLOBAL$`),
@@ -379,16 +374,16 @@ function transform(file, sourceCode, { uniqueID = "00000000000", scriptUser, scr
379
374
  } else globalBlockVariables.add(declarator.id.name)
380
375
  } else if ("ClassDeclaration" == globalBlockStatement.type) {
381
376
  program.scope.crawl()
382
- assert(globalBlockStatement.id, "src/processScript/transform.ts:487:37")
377
+ assert(globalBlockStatement.id, "src/processScript/transform.ts:480:37")
383
378
  if (program.scope.hasGlobal(globalBlockStatement.id.name)) {
384
379
  globalBlock.body.splice(globalBlockIndex, 1)
385
380
  const [globalBlockPath] = program.unshiftContainer("body", globalBlock),
386
381
  [globalBlockStatementPath] = program.unshiftContainer("body", globalBlockStatement)
387
382
  program.scope.crawl()
388
383
  const binding = program.scope.getBinding(globalBlockStatement.id.name)
389
- assert(binding, "src/processScript/transform.ts:499:22")
384
+ assert(binding, "src/processScript/transform.ts:492:22")
390
385
  for (const referencePath of binding.referencePaths) {
391
- assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:502:55")
386
+ assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:495:55")
392
387
  referencePath.replaceWith(
393
388
  t.memberExpression(
394
389
  t.identifier(`$${uniqueID}$GLOBAL$`),
@@ -555,7 +550,7 @@ function transform(file, sourceCode, { uniqueID = "00000000000", scriptUser, scr
555
550
  }
556
551
  },
557
552
  ClassBody({ node: classBody, scope, parent }) {
558
- assert(t.isClass(parent), "src/processScript/transform.ts:669:30")
553
+ assert(t.isClass(parent), "src/processScript/transform.ts:662:30")
559
554
  let thisIsReferenced = !1
560
555
  for (const classMethod of classBody.body) {
561
556
  if ("ClassMethod" != classMethod.type) continue
@@ -661,23 +656,23 @@ function transform(file, sourceCode, { uniqueID = "00000000000", scriptUser, scr
661
656
  }
662
657
  function processFakeSubscriptObject(fakeSubscriptObjectName) {
663
658
  for (const referencePath of getReferencePathsToGlobal(fakeSubscriptObjectName, program)) {
664
- assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:783:60")
659
+ assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:776:60")
665
660
  assert("Identifier" == referencePath.parent.property.type)
666
661
  assert(
667
662
  "MemberExpression" == referencePath.parentPath.parentPath?.node.type,
668
- "src/processScript/transform.ts:785:81"
663
+ "src/processScript/transform.ts:778:81"
669
664
  )
670
665
  assert(
671
666
  "Identifier" == referencePath.parentPath.parentPath.node.property.type,
672
- "src/processScript/transform.ts:786:83"
667
+ "src/processScript/transform.ts:779:83"
673
668
  )
674
669
  assert(
675
670
  /^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parent.property.name),
676
- `src/processScript/transform.ts:790:8 invalid user "${referencePath.parent.property.name}" in subscript`
671
+ `src/processScript/transform.ts:783:8 invalid user "${referencePath.parent.property.name}" in subscript`
677
672
  )
678
673
  assert(
679
674
  /^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parentPath.parentPath.node.property.name),
680
- `src/processScript/transform.ts:795:8 invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
675
+ `src/processScript/transform.ts:788:8 invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
681
676
  )
682
677
  if ("CallExpression" == referencePath.parentPath.parentPath.parentPath?.type)
683
678
  referencePath.parentPath.parentPath.replaceWith(
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 sourcePath directory containing source code
25
- * @param hackmudPath directory created by hackmud containing user data including scripts
24
+ * @param sourceDirectory directory containing source code
25
+ * @param hackmudDirectory 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(sourcePath: string, hackmudPath: string, { scripts, onPush, minify, mangleNames, forceQuineCheats }?: PushOptions): Promise<Info[]>;
28
+ export declare function push(sourceDirectory: string, hackmudDirectory: 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"
3
2
  import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
4
3
  import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
5
4
  import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
6
5
  import { readFile } from "fs/promises"
7
- import { basename, resolve } from "path"
6
+ import { basename, resolve, extname } from "path"
7
+ import { supportedExtensions } from "./constants.js"
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"
32
33
  import "prettier"
33
34
  import "rollup"
34
- import "./constants.js"
35
35
  import "./processScript/minify.js"
36
36
  import "@samual/lib/spliceString"
37
37
  import "acorn"
@@ -43,96 +43,227 @@ import "import-meta-resolve"
43
43
  import "./processScript/transform.js"
44
44
  import "@samual/lib/clearObject"
45
45
  async function push(
46
- sourcePath,
47
- hackmudPath,
46
+ sourceDirectory,
47
+ hackmudDirectory,
48
48
  { scripts = ["*.*"], onPush = () => {}, minify = !0, mangleNames = !1, forceQuineCheats } = {}
49
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)
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)
72
62
  }
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)
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
+ }
83
88
  }
84
89
  await Promise.all(
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
- }
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
+ )
96
131
  })
97
132
  )
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 = []
106
133
  await Promise.all(
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}`)
129
- )
130
- )
131
- )
132
- allInfo.push(info)
133
- onPush(info)
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
+ ))
134
171
  })
135
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
+ )
215
+ )
216
+ allInfo.push(info)
217
+ onPush(info)
218
+ }
219
+ )
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
+ ))
136
267
  return allInfo
137
268
  }
138
269
  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: "utf8" }).then(file =>
15
+ readFile(resolve(hackmudPath, file.name), { encoding: "utf-8" }).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?.({ path, users: [], characterCount: 0, error: Error("no users to push to") })
119
+ onPush?.({ file: path, users: [], minLength: 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: "utf8" }), {
128
+ ;({ script: minifiedCode } = await processScript(await readFile(filePath, { encoding: "utf-8" }), {
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?.({ path, users: [], characterCount: 0, error })
139
+ onPush?.({ file: path, users: [], minLength: 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
- path,
153
+ file: path,
154
154
  users: usersToPushTo,
155
- characterCount: countHackmudCharacters(minifiedCode),
155
+ minLength: 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: "utf8" })
171
+ sourceCode = await readFile(filePath, { encoding: "utf-8" })
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?.({ path, users: [], characterCount: 0, error })
184
+ onPush?.({ file: path, users: [], minLength: 0, error })
185
185
  return
186
186
  }
187
187
  await writeFilePersistent(resolve(hackmudDirectory, user, "scripts", scriptName + ".js"), script)
188
- onPush?.({ path, users: [user], characterCount: countHackmudCharacters(script), error: void 0 })
188
+ onPush?.({ file: path, users: [user], minLength: countHackmudCharacters(script), error: void 0 })
189
189
  })
190
190
  onReady && watcher.on("ready", onReady)
191
191
  if (!typeDeclarationPath_) return