hackmud-script-manager 0.19.1-98e81f8 → 0.19.1-b040eb5
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/README.md +1 -1
- package/bin/hsm.d.ts +0 -0
- package/bin/hsm.js +147 -300
- package/env.d.ts +1357 -0
- package/generateTypeDeclaration.d.ts +1 -2
- package/generateTypeDeclaration.js +19 -19
- package/index.d.ts +2 -2
- package/index.js +2 -1
- package/package.json +8 -6
- package/processScript/index.d.ts +17 -26
- package/processScript/index.js +258 -241
- package/processScript/minify.d.ts +15 -21
- package/processScript/minify.js +381 -395
- package/processScript/postprocess.d.ts +0 -1
- package/processScript/postprocess.js +1 -1
- package/processScript/preprocess.d.ts +6 -9
- package/processScript/preprocess.js +94 -94
- package/processScript/shared.d.ts +1 -1
- package/processScript/shared.js +11 -11
- package/processScript/transform.d.ts +13 -18
- package/processScript/transform.js +597 -550
- package/pull.d.ts +5 -9
- package/pull.js +2 -2
- package/push.d.ts +24 -33
- package/push.js +88 -213
- package/syncMacros.d.ts +1 -2
- package/syncMacros.js +7 -6
- package/watch.d.ts +10 -16
- package/watch.js +30 -31
- package/tsconfig.tsbuildinfo +0 -1
package/pull.d.ts
CHANGED
@@ -1,9 +1,5 @@
|
|
1
|
-
/**
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
-
|
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
|
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
|
-
|
6
|
-
/**
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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 {
|
5
|
-
import {
|
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
|
-
|
45
|
-
|
46
|
-
|
45
|
+
async function push(
|
46
|
+
sourcePath,
|
47
|
+
hackmudPath,
|
47
48
|
{ scripts = ["*.*"], onPush = () => {}, minify = !0, mangleNames = !1, forceQuineCheats } = {}
|
48
|
-
)
|
49
|
-
const
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
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
|
-
|
88
|
-
await
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
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
|
-
[...
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
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
|
-
|
211
|
-
onPush(info)
|
212
|
-
}
|
130
|
+
)
|
213
131
|
)
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
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
|
138
|
+
export { push }
|
package/syncMacros.d.ts
CHANGED
package/syncMacros.js
CHANGED
@@ -1,17 +1,18 @@
|
|
1
|
-
import {
|
1
|
+
import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
|
2
|
+
import { readFile, stat, writeFile } from "fs/promises"
|
2
3
|
import { extname, basename, resolve } from "path"
|
3
|
-
|
4
|
-
const files = await
|
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: "
|
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
|
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
|
-
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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 {
|
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
|
-
|
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
|
95
|
-
if (
|
96
|
-
for (const
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
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
|
109
|
-
|
110
|
-
for (const
|
111
|
-
|
112
|
-
usersToPushToSet.add(
|
113
|
-
:
|
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?.({
|
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: "
|
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?.({
|
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
|
-
|
153
|
+
path,
|
155
154
|
users: usersToPushTo,
|
156
|
-
|
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: "
|
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?.({
|
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?.({
|
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
|
208
|
+
export { watch }
|