spotifyplus 0.1.3 → 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.
Files changed (2) hide show
  1. package/dev.cjs +42 -82
  2. 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 DEFAULT_MODULE_PACKAGE = "com.lenerd.spotifyplus";
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 HTTP/reverse port (default: ${DEFAULT_PORT})
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
  `);
@@ -160,36 +148,6 @@ async function resolveEntryPath(scriptDir, manifest) {
160
148
  }
161
149
  throw new Error(`Could not resolve ${manifestEntry}. Set manifest.main to a real source file, or add src/index.tsx.`);
162
150
  }
163
- function createReloadServer(state, port) {
164
- const server = import_node_http.default.createServer((request, response) => {
165
- const url = new URL(request.url ?? "/", `http://127.0.0.1:${port}`);
166
- const match = /^\/reload\/([^/]+)\/([^/]+)\.json$/.exec(url.pathname);
167
- if (!match) {
168
- response.writeHead(404, { "content-type": "application/json" });
169
- response.end(JSON.stringify({ error: "not found" }));
170
- return;
171
- }
172
- const [, buildId, scriptId] = match;
173
- const current = state.currentBuild;
174
- if (!current || current.buildId !== buildId || current.manifest.id !== decodeURIComponent(scriptId)) {
175
- response.writeHead(404, { "content-type": "application/json" });
176
- response.end(JSON.stringify({ error: "build not found" }));
177
- return;
178
- }
179
- response.writeHead(200, {
180
- "content-type": "application/json; charset=utf-8",
181
- "cache-control": "no-store"
182
- });
183
- response.end(JSON.stringify(current));
184
- });
185
- return new Promise((resolve, reject) => {
186
- server.once("error", reject);
187
- server.listen(port, "127.0.0.1", () => {
188
- server.off("error", reject);
189
- resolve(server);
190
- });
191
- });
192
- }
193
151
  async function adb(options, args) {
194
152
  const fullArgs = [];
195
153
  if (options.device) fullArgs.push("-s", options.device);
@@ -204,37 +162,43 @@ async function adb(options, args) {
204
162
  }
205
163
  }
206
164
  async function notifyDevice(options, buildInfo) {
207
- const encodedScriptId = encodeURIComponent(buildInfo.manifest.id);
208
- const url = `http://127.0.0.1:${options.port}/reload/${buildInfo.buildId}/${encodedScriptId}.json`;
209
- await adb(options, ["reverse", `tcp:${options.port}`, `tcp:${options.port}`]);
210
- await adb(options, [
211
- "shell",
212
- "am",
213
- "broadcast",
214
- "-a",
215
- START_BRIDGE_ACTION,
216
- "-n",
217
- `${options.modulePackage}/.manager.bridge.BridgeStartReceiver`
218
- ]);
219
- await adb(options, [
220
- "shell",
221
- "am",
222
- "broadcast",
223
- "-a",
224
- HOT_RELOAD_ACTION,
225
- "-n",
226
- `${options.modulePackage}/.manager.bridge.HotReloadReceiver`,
227
- "--es",
228
- "scriptId",
229
- buildInfo.manifest.id,
230
- "--es",
231
- "buildId",
232
- buildInfo.buildId,
233
- "--es",
234
- "url",
235
- url
236
- ]);
237
- return url;
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
+ });
238
202
  }
239
203
  function shouldWatchFile(filePath) {
240
204
  return WATCH_EXTENSIONS.has(import_node_path.default.extname(filePath).toLowerCase());
@@ -283,9 +247,8 @@ async function run() {
283
247
  printHelp();
284
248
  return;
285
249
  }
286
- const state = { currentBuild: null };
287
- const server = await createReloadServer(state, options.port);
288
- 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`);
289
252
  console.log(`[spotifyplus] watching ${options.scriptDir}`);
290
253
  let buildInFlight = false;
291
254
  let pendingBuild = false;
@@ -297,10 +260,8 @@ async function run() {
297
260
  buildInFlight = true;
298
261
  try {
299
262
  const buildInfo = await bundleScript(options.scriptDir);
300
- state.currentBuild = buildInfo;
301
- const url = await notifyDevice(options, buildInfo);
263
+ await notifyDevice(options, buildInfo);
302
264
  console.log(`[spotifyplus] reloaded ${buildInfo.manifest.id} (${buildInfo.buildId})`);
303
- console.log(`[spotifyplus] served ${url}`);
304
265
  } catch (error) {
305
266
  console.error(`[spotifyplus] ${reason} failed`);
306
267
  console.error(error?.message ?? error);
@@ -324,7 +285,6 @@ async function run() {
324
285
  await rebuild("initial build");
325
286
  const close = () => {
326
287
  closeWatchers();
327
- server.close();
328
288
  process.exit(0);
329
289
  };
330
290
  process.on("SIGINT", close);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spotifyplus",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "type": "commonjs",
5
5
  "main": "./index.cjs",
6
6
  "types": "./index.d.ts",