hackmud-script-manager 0.19.0 → 0.19.1-4bde221

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/watch.js CHANGED
@@ -1 +1,209 @@
1
- import{DynamicMap as r}from"@samual/lib/DynamicMap";import{assert as t}from"@samual/lib/assert";import{countHackmudCharacters as e}from"@samual/lib/countHackmudCharacters";import{writeFilePersistent as i}from"@samual/lib/writeFilePersistent";import{watch as o}from"chokidar";import{readdir as a,readFile as s,writeFile as n}from"fs/promises";import{extname as p,basename as l,resolve as m}from"path";import{supportedExtensions as c}from"./constants.js";import{generateTypeDeclaration as f}from"./generateTypeDeclaration.js";import{processScript as u}from"./processScript/index.js";import"@babel/generator";import"@babel/parser";import"@babel/plugin-proposal-decorators";import"@babel/plugin-proposal-destructuring-private";import"@babel/plugin-proposal-explicit-resource-management";import"@babel/plugin-transform-class-properties";import"@babel/plugin-transform-class-static-block";import"@babel/plugin-transform-exponentiation-operator";import"@babel/plugin-transform-json-strings";import"@babel/plugin-transform-logical-assignment-operators";import"@babel/plugin-transform-nullish-coalescing-operator";import"@babel/plugin-transform-numeric-separator";import"@babel/plugin-transform-object-rest-spread";import"@babel/plugin-transform-optional-catch-binding";import"@babel/plugin-transform-optional-chaining";import"@babel/plugin-transform-private-property-in-object";import"@babel/plugin-transform-unicode-sets-regex";import"@babel/traverse";import"@babel/types";import"@rollup/plugin-babel";import"@rollup/plugin-commonjs";import"@rollup/plugin-json";import"@rollup/plugin-node-resolve";import"prettier";import"rollup";import"./processScript/minify.js";import"@samual/lib/spliceString";import"acorn";import"terser";import"./processScript/shared.js";import"./processScript/postprocess.js";import"./processScript/preprocess.js";import"import-meta-resolve";import"./processScript/transform.js";import"@samual/lib/clearObject";const watch=async(d,g,{scripts:b=["*.*"],onPush:h,minify:w=!0,mangleNames:y=!1,typeDeclarationPath:j,onReady:S,forceQuineCheats:v}={})=>{if(!b.length)throw new Error("scripts option was an empty array");const $=new r((r=>new Set)),E=new Set,F=new Set;let P=!1;for(const r of b){const[t,e]=r.split(".");t&&"*"!=t?e&&"*"!=e?$.get(e).add(t):E.add(t):e&&"*"!=e?F.add(e):P=!0}const D=o(["*/*.ts","*/*.js"],{cwd:d,awaitWriteFinish:{stabilityThreshold:100},ignored:"*.d.ts"}).on("change",(async o=>{if(o.endsWith(".d.ts"))return;const n=p(o);if(!c.includes(n))return;const f=l(o,n);if(o==l(o)){if(!(P||E.size||F.has(f)||$.has(f)))return;const n=new r((r=>[]));await Promise.all((await a(d,{withFileTypes:!0})).map((async r=>{if(r.isDirectory())for(const t of await a(m(d,r.name),{withFileTypes:!0})){if(!t.isFile())continue;const e=p(t.name);c.includes(e)&&n.get(l(t.name,e)).push(r.name)}})));const b=new Set;if(P||F.has(f)){for(const r of await a(m(d),{withFileTypes:!0}))r.isDirectory()&&b.add(r.name);for(const r of await a(m(g),{withFileTypes:!0}))r.isDirectory()?b.add(r.name):r.isFile()&&r.name.endsWith(".key")&&b.add(r.name.slice(0,-4));for(const r of $.values())for(const t of r)b.add(t)}for(const r of E)b.add(r);for(const r of $.get(f))b.add(r);const j=[...b].filter((r=>!n.has(r)));if(!j.length)return void h?.({file:o,users:[],minLength:0,error:new Error("no users to push to")});const S=Math.floor(Math.random()*2**52).toString(36).padStart(11,"0"),D=m(d,o);let T;try{({script:T}=await u(await s(D,{encoding:"utf-8"}),{minify:w,scriptUser:!0,scriptName:f,uniqueID:S,filePath:D,mangleNames:y,forceQuineCheats:v}))}catch(r){return t(r instanceof Error),void h?.({file:o,users:[],minLength:0,error:r})}return await Promise.all(j.map((r=>i(m(g,r,`scripts/${f}.js`),T.replace(new RegExp(`\\$${S}\\$SCRIPT_USER\\$`,"g"),r).replace(new RegExp(`\\$${S}\\$FULL_SCRIPT_NAME\\$`,"g"),`${r}.${f}`))))),void h?.({file:o,users:j,minLength:e(T),error:void 0})}const b=l(m(o,".."));if(!(P||E.size||F.has(f)||$.get(f).has(b)))return;const j=m(d,o),S=await s(j,{encoding:"utf-8"});let D;try{({script:D}=await u(S,{minify:w,scriptUser:b,scriptName:f,filePath:j,mangleNames:y,forceQuineCheats:v}))}catch(r){return t(r instanceof Error),void h?.({file:o,users:[],minLength:0,error:r})}await i(m(g,b,"scripts",`${f}.js`),D),h?.({file:o,users:[b],minLength:e(D),error:void 0})}));if(S&&D.on("ready",S),!j)return;let T=j;const writeTypeDeclaration=async()=>{const r=await f(d,g);try{await n(T,r)}catch(e){if(t(e instanceof Error),"EISDIR"!=e.code)throw e;T=m(T,"player.d.ts"),await n(T,r)}};await writeTypeDeclaration(),D.on("add",writeTypeDeclaration),D.on("unlink",writeTypeDeclaration)};export{watch as default,watch};
1
+ import { Cache } from "@samual/lib/Cache"
2
+ import { assert } from "@samual/lib/assert"
3
+ import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
4
+ import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
5
+ import { watch as watch$1 } from "chokidar"
6
+ import { readdir, readFile, writeFile } from "fs/promises"
7
+ import { extname, basename, resolve } from "path"
8
+ import { supportedExtensions } from "./constants.js"
9
+ import { generateTypeDeclaration } from "./generateTypeDeclaration.js"
10
+ import { processScript } from "./processScript/index.js"
11
+ import "@babel/generator"
12
+ import "@babel/parser"
13
+ import "@babel/plugin-proposal-decorators"
14
+ import "@babel/plugin-proposal-destructuring-private"
15
+ import "@babel/plugin-proposal-explicit-resource-management"
16
+ import "@babel/plugin-transform-class-properties"
17
+ import "@babel/plugin-transform-class-static-block"
18
+ import "@babel/plugin-transform-exponentiation-operator"
19
+ import "@babel/plugin-transform-json-strings"
20
+ import "@babel/plugin-transform-logical-assignment-operators"
21
+ import "@babel/plugin-transform-nullish-coalescing-operator"
22
+ import "@babel/plugin-transform-numeric-separator"
23
+ import "@babel/plugin-transform-object-rest-spread"
24
+ import "@babel/plugin-transform-optional-catch-binding"
25
+ import "@babel/plugin-transform-optional-chaining"
26
+ import "@babel/plugin-transform-private-property-in-object"
27
+ import "@babel/plugin-transform-unicode-sets-regex"
28
+ import "@babel/traverse"
29
+ import "@babel/types"
30
+ import "@rollup/plugin-babel"
31
+ import "@rollup/plugin-commonjs"
32
+ import "@rollup/plugin-json"
33
+ import "@rollup/plugin-node-resolve"
34
+ import "prettier"
35
+ import "rollup"
36
+ import "./processScript/minify.js"
37
+ import "@samual/lib/spliceString"
38
+ import "acorn"
39
+ import "terser"
40
+ import "./processScript/shared.js"
41
+ import "./processScript/postprocess.js"
42
+ import "./processScript/preprocess.js"
43
+ import "import-meta-resolve"
44
+ import "./processScript/transform.js"
45
+ import "@samual/lib/clearObject"
46
+ const watch = async (
47
+ sourceDirectory,
48
+ hackmudDirectory,
49
+ {
50
+ scripts = ["*.*"],
51
+ onPush,
52
+ minify = !0,
53
+ mangleNames = !1,
54
+ typeDeclarationPath: typeDeclarationPath_,
55
+ onReady,
56
+ forceQuineCheats
57
+ } = {}
58
+ ) => {
59
+ if (!scripts.length) throw Error("scripts option was an empty array")
60
+ const scriptNamesToUsers = new Cache(_scriptName => new Set()),
61
+ wildScriptUsers = new Set(),
62
+ wildUserScripts = new Set()
63
+ let pushEverything = !1
64
+ for (const fullScriptName of scripts) {
65
+ const [user, scriptName] = fullScriptName.split(".")
66
+ user && "*" != user ?
67
+ scriptName && "*" != scriptName ?
68
+ scriptNamesToUsers.get(scriptName).add(user)
69
+ : wildScriptUsers.add(user)
70
+ : scriptName && "*" != scriptName ? wildUserScripts.add(scriptName)
71
+ : (pushEverything = !0)
72
+ }
73
+ const watcher = watch$1(["*/*.ts", "*/*.js"], {
74
+ cwd: sourceDirectory,
75
+ awaitWriteFinish: { stabilityThreshold: 100 },
76
+ ignored: "*.d.ts"
77
+ }).on("change", async path => {
78
+ if (path.endsWith(".d.ts")) return
79
+ const extension = extname(path)
80
+ if (!supportedExtensions.includes(extension)) return
81
+ const scriptName = basename(path, extension)
82
+ if (path == basename(path)) {
83
+ if (
84
+ !(
85
+ pushEverything ||
86
+ wildScriptUsers.size ||
87
+ wildUserScripts.has(scriptName) ||
88
+ scriptNamesToUsers.has(scriptName)
89
+ )
90
+ )
91
+ return
92
+ const scriptNamesToUsersToSkip = new Cache(_scriptName => [])
93
+ 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
+ }
104
+ })
105
+ )
106
+ const usersToPushToSet = new Set()
107
+ 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))
114
+ for (const users of scriptNamesToUsers.values()) for (const user of users) usersToPushToSet.add(user)
115
+ }
116
+ for (const user of wildScriptUsers) usersToPushToSet.add(user)
117
+ for (const user of scriptNamesToUsers.get(scriptName)) usersToPushToSet.add(user)
118
+ const usersToPushTo = [...usersToPushToSet].filter(user => !scriptNamesToUsersToSkip.has(user))
119
+ if (!usersToPushTo.length) {
120
+ onPush?.({ file: path, users: [], minLength: 0, error: Error("no users to push to") })
121
+ return
122
+ }
123
+ const uniqueID = Math.floor(Math.random() * 2 ** 52)
124
+ .toString(36)
125
+ .padStart(11, "0"),
126
+ filePath = resolve(sourceDirectory, path)
127
+ let minifiedCode
128
+ try {
129
+ ;({ script: minifiedCode } = await processScript(await readFile(filePath, { encoding: "utf-8" }), {
130
+ minify,
131
+ scriptUser: !0,
132
+ scriptName,
133
+ uniqueID,
134
+ filePath,
135
+ mangleNames,
136
+ forceQuineCheats
137
+ }))
138
+ } catch (error) {
139
+ assert(error instanceof Error)
140
+ onPush?.({ file: path, users: [], minLength: 0, error })
141
+ return
142
+ }
143
+ await Promise.all(
144
+ usersToPushTo.map(user =>
145
+ writeFilePersistent(
146
+ resolve(hackmudDirectory, user, `scripts/${scriptName}.js`),
147
+ minifiedCode
148
+ .replace(RegExp(`\\$${uniqueID}\\$SCRIPT_USER\\$`, "g"), user)
149
+ .replace(RegExp(`\\$${uniqueID}\\$FULL_SCRIPT_NAME\\$`, "g"), `${user}.${scriptName}`)
150
+ )
151
+ )
152
+ )
153
+ onPush?.({
154
+ file: path,
155
+ users: usersToPushTo,
156
+ minLength: countHackmudCharacters(minifiedCode),
157
+ error: void 0
158
+ })
159
+ return
160
+ }
161
+ const user = basename(resolve(path, ".."))
162
+ if (
163
+ !(
164
+ pushEverything ||
165
+ wildScriptUsers.size ||
166
+ wildUserScripts.has(scriptName) ||
167
+ scriptNamesToUsers.get(scriptName).has(user)
168
+ )
169
+ )
170
+ return
171
+ const filePath = resolve(sourceDirectory, path),
172
+ sourceCode = await readFile(filePath, { encoding: "utf-8" })
173
+ let script
174
+ try {
175
+ ;({ script } = await processScript(sourceCode, {
176
+ minify,
177
+ scriptUser: user,
178
+ scriptName,
179
+ filePath,
180
+ mangleNames,
181
+ forceQuineCheats
182
+ }))
183
+ } catch (error) {
184
+ assert(error instanceof Error)
185
+ onPush?.({ file: path, users: [], minLength: 0, error })
186
+ return
187
+ }
188
+ await writeFilePersistent(resolve(hackmudDirectory, user, "scripts", scriptName + ".js"), script)
189
+ onPush?.({ file: path, users: [user], minLength: countHackmudCharacters(script), error: void 0 })
190
+ })
191
+ onReady && watcher.on("ready", onReady)
192
+ if (!typeDeclarationPath_) return
193
+ let typeDeclarationPath = typeDeclarationPath_
194
+ const writeTypeDeclaration = async () => {
195
+ const typeDeclaration = await generateTypeDeclaration(sourceDirectory, hackmudDirectory)
196
+ try {
197
+ await writeFile(typeDeclarationPath, typeDeclaration)
198
+ } catch (error) {
199
+ assert(error instanceof Error)
200
+ if ("EISDIR" != error.code) throw error
201
+ typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
202
+ await writeFile(typeDeclarationPath, typeDeclaration)
203
+ }
204
+ }
205
+ await writeTypeDeclaration()
206
+ watcher.on("add", writeTypeDeclaration)
207
+ watcher.on("unlink", writeTypeDeclaration)
208
+ }
209
+ export { watch as default, watch }