spotifyplus 0.1.2 → 0.1.4
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/dev.cjs +62 -81
- package/package.json +1 -1
package/dev.cjs
CHANGED
|
@@ -32,9 +32,7 @@ var import_node_util = require("node:util");
|
|
|
32
32
|
var import_esbuild = require("esbuild");
|
|
33
33
|
var execFile = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
34
34
|
var DEFAULT_PORT = 37846;
|
|
35
|
-
var
|
|
36
|
-
var START_BRIDGE_ACTION = "com.lenerd.spotifyplus.action.START_BRIDGE";
|
|
37
|
-
var HOT_RELOAD_ACTION = "com.lenerd.spotifyplus.action.HOT_RELOAD";
|
|
35
|
+
var RUNTIME_PORT = 37846;
|
|
38
36
|
var WATCH_EXTENSIONS = /* @__PURE__ */ new Set([".js", ".jsx", ".ts", ".tsx", ".json"]);
|
|
39
37
|
var IGNORED_DIRECTORIES = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", "build", ".gradle"]);
|
|
40
38
|
function parseArgs(argv) {
|
|
@@ -43,8 +41,6 @@ function parseArgs(argv) {
|
|
|
43
41
|
adb: process.env.ADB || "adb",
|
|
44
42
|
device: "",
|
|
45
43
|
port: DEFAULT_PORT,
|
|
46
|
-
modulePackage: DEFAULT_MODULE_PACKAGE,
|
|
47
|
-
spotifyPackage: "com.spotify.music",
|
|
48
44
|
debounceMs: 150,
|
|
49
45
|
help: false
|
|
50
46
|
};
|
|
@@ -72,12 +68,6 @@ function parseArgs(argv) {
|
|
|
72
68
|
case "port":
|
|
73
69
|
options.port = parseInteger(value, "--port");
|
|
74
70
|
break;
|
|
75
|
-
case "module-package":
|
|
76
|
-
options.modulePackage = value;
|
|
77
|
-
break;
|
|
78
|
-
case "spotify-package":
|
|
79
|
-
options.spotifyPackage = value;
|
|
80
|
-
break;
|
|
81
71
|
case "debounce-ms":
|
|
82
72
|
options.debounceMs = parseInteger(value, "--debounce-ms");
|
|
83
73
|
break;
|
|
@@ -101,9 +91,7 @@ function printHelp() {
|
|
|
101
91
|
Options:
|
|
102
92
|
--adb <path> adb executable to use (default: adb)
|
|
103
93
|
--device <serial> adb device serial
|
|
104
|
-
--port <port> local
|
|
105
|
-
--module-package <name> SpotifyPlus manager app package (default: ${DEFAULT_MODULE_PACKAGE})
|
|
106
|
-
--spotify-package <name> Spotify app package, reserved for future checks (default: com.spotify.music)
|
|
94
|
+
--port <port> local forwarded hot reload port (default: ${DEFAULT_PORT})
|
|
107
95
|
--debounce-ms <ms> file change debounce (default: 150)
|
|
108
96
|
--help, -h show this help
|
|
109
97
|
`);
|
|
@@ -119,7 +107,7 @@ async function readManifest(scriptDir) {
|
|
|
119
107
|
}
|
|
120
108
|
async function bundleScript(scriptDir) {
|
|
121
109
|
const manifest = await readManifest(scriptDir);
|
|
122
|
-
const entryPath =
|
|
110
|
+
const entryPath = await resolveEntryPath(scriptDir, manifest);
|
|
123
111
|
const result = await (0, import_esbuild.build)({
|
|
124
112
|
entryPoints: [entryPath],
|
|
125
113
|
bundle: true,
|
|
@@ -139,35 +127,26 @@ async function bundleScript(scriptDir) {
|
|
|
139
127
|
source
|
|
140
128
|
};
|
|
141
129
|
}
|
|
142
|
-
function
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
130
|
+
async function resolveEntryPath(scriptDir, manifest) {
|
|
131
|
+
const manifestEntry = import_node_path.default.resolve(scriptDir, manifest.main);
|
|
132
|
+
if (import_node_fs.default.existsSync(manifestEntry)) return manifestEntry;
|
|
133
|
+
const candidates = [
|
|
134
|
+
"src/index.tsx",
|
|
135
|
+
"src/index.ts",
|
|
136
|
+
"src/index.jsx",
|
|
137
|
+
"src/index.js",
|
|
138
|
+
"index.tsx",
|
|
139
|
+
"index.ts",
|
|
140
|
+
"index.jsx"
|
|
141
|
+
];
|
|
142
|
+
for (const candidate of candidates) {
|
|
143
|
+
const candidatePath = import_node_path.default.resolve(scriptDir, candidate);
|
|
144
|
+
if (import_node_fs.default.existsSync(candidatePath)) {
|
|
145
|
+
console.warn(`[spotifyplus] manifest.main points to missing ${manifest.main}; using ${candidate} as the dev entry`);
|
|
146
|
+
return candidatePath;
|
|
150
147
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if (!current || current.buildId !== buildId || current.manifest.id !== decodeURIComponent(scriptId)) {
|
|
154
|
-
response.writeHead(404, { "content-type": "application/json" });
|
|
155
|
-
response.end(JSON.stringify({ error: "build not found" }));
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
response.writeHead(200, {
|
|
159
|
-
"content-type": "application/json; charset=utf-8",
|
|
160
|
-
"cache-control": "no-store"
|
|
161
|
-
});
|
|
162
|
-
response.end(JSON.stringify(current));
|
|
163
|
-
});
|
|
164
|
-
return new Promise((resolve, reject) => {
|
|
165
|
-
server.once("error", reject);
|
|
166
|
-
server.listen(port, "127.0.0.1", () => {
|
|
167
|
-
server.off("error", reject);
|
|
168
|
-
resolve(server);
|
|
169
|
-
});
|
|
170
|
-
});
|
|
148
|
+
}
|
|
149
|
+
throw new Error(`Could not resolve ${manifestEntry}. Set manifest.main to a real source file, or add src/index.tsx.`);
|
|
171
150
|
}
|
|
172
151
|
async function adb(options, args) {
|
|
173
152
|
const fullArgs = [];
|
|
@@ -183,37 +162,43 @@ async function adb(options, args) {
|
|
|
183
162
|
}
|
|
184
163
|
}
|
|
185
164
|
async function notifyDevice(options, buildInfo) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
165
|
+
await adb(options, ["forward", `tcp:${options.port}`, `tcp:${RUNTIME_PORT}`]);
|
|
166
|
+
await postHotReloadBundle(options.port, buildInfo);
|
|
167
|
+
}
|
|
168
|
+
function postHotReloadBundle(port, buildInfo) {
|
|
169
|
+
const body = JSON.stringify(buildInfo);
|
|
170
|
+
return new Promise((resolve, reject) => {
|
|
171
|
+
const request = import_node_http.default.request({
|
|
172
|
+
host: "127.0.0.1",
|
|
173
|
+
port,
|
|
174
|
+
path: "/hot-reload",
|
|
175
|
+
method: "POST",
|
|
176
|
+
headers: {
|
|
177
|
+
"content-type": "application/json; charset=utf-8",
|
|
178
|
+
"content-length": Buffer.byteLength(body)
|
|
179
|
+
}
|
|
180
|
+
}, (response) => {
|
|
181
|
+
response.setEncoding("utf8");
|
|
182
|
+
let responseBody = "";
|
|
183
|
+
response.on("data", (chunk) => {
|
|
184
|
+
responseBody += chunk;
|
|
185
|
+
});
|
|
186
|
+
response.on("end", () => {
|
|
187
|
+
if ((response.statusCode ?? 0) >= 200 && (response.statusCode ?? 0) < 300) {
|
|
188
|
+
resolve(responseBody);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
reject(new Error(`SpotifyPlus runtime returned HTTP ${response.statusCode}: ${responseBody}`));
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
request.on("error", (error) => {
|
|
195
|
+
reject(new Error(`Could not reach SpotifyPlus runtime on forwarded port ${port}. Open Spotify and wait for the script runtime to start, then try again. ${error.message}`));
|
|
196
|
+
});
|
|
197
|
+
request.setTimeout(5e3, () => {
|
|
198
|
+
request.destroy(new Error(`Timed out connecting to SpotifyPlus runtime on forwarded port ${port}`));
|
|
199
|
+
});
|
|
200
|
+
request.end(body);
|
|
201
|
+
});
|
|
217
202
|
}
|
|
218
203
|
function shouldWatchFile(filePath) {
|
|
219
204
|
return WATCH_EXTENSIONS.has(import_node_path.default.extname(filePath).toLowerCase());
|
|
@@ -262,9 +247,8 @@ async function run() {
|
|
|
262
247
|
printHelp();
|
|
263
248
|
return;
|
|
264
249
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
console.log(`[spotifyplus] dev server listening on http://127.0.0.1:${options.port}`);
|
|
250
|
+
await adb(options, ["forward", `tcp:${options.port}`, `tcp:${RUNTIME_PORT}`]);
|
|
251
|
+
console.log(`[spotifyplus] forwarding http://127.0.0.1:${options.port} to the SpotifyPlus runtime`);
|
|
268
252
|
console.log(`[spotifyplus] watching ${options.scriptDir}`);
|
|
269
253
|
let buildInFlight = false;
|
|
270
254
|
let pendingBuild = false;
|
|
@@ -276,10 +260,8 @@ async function run() {
|
|
|
276
260
|
buildInFlight = true;
|
|
277
261
|
try {
|
|
278
262
|
const buildInfo = await bundleScript(options.scriptDir);
|
|
279
|
-
|
|
280
|
-
const url = await notifyDevice(options, buildInfo);
|
|
263
|
+
await notifyDevice(options, buildInfo);
|
|
281
264
|
console.log(`[spotifyplus] reloaded ${buildInfo.manifest.id} (${buildInfo.buildId})`);
|
|
282
|
-
console.log(`[spotifyplus] served ${url}`);
|
|
283
265
|
} catch (error) {
|
|
284
266
|
console.error(`[spotifyplus] ${reason} failed`);
|
|
285
267
|
console.error(error?.message ?? error);
|
|
@@ -303,7 +285,6 @@ async function run() {
|
|
|
303
285
|
await rebuild("initial build");
|
|
304
286
|
const close = () => {
|
|
305
287
|
closeWatchers();
|
|
306
|
-
server.close();
|
|
307
288
|
process.exit(0);
|
|
308
289
|
};
|
|
309
290
|
process.on("SIGINT", close);
|