azul-sync 1.3.0

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 (133) hide show
  1. package/.gitattributes +1 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  4. package/README.md +142 -0
  5. package/dist/build.d.ts +19 -0
  6. package/dist/build.d.ts.map +1 -0
  7. package/dist/build.js +92 -0
  8. package/dist/build.js.map +1 -0
  9. package/dist/cli.d.ts +3 -0
  10. package/dist/cli.d.ts.map +1 -0
  11. package/dist/cli.js +397 -0
  12. package/dist/cli.js.map +1 -0
  13. package/dist/config.d.ts +26 -0
  14. package/dist/config.d.ts.map +1 -0
  15. package/dist/config.js +105 -0
  16. package/dist/config.js.map +1 -0
  17. package/dist/fs/fileWriter.d.ts +100 -0
  18. package/dist/fs/fileWriter.d.ts.map +1 -0
  19. package/dist/fs/fileWriter.js +342 -0
  20. package/dist/fs/fileWriter.js.map +1 -0
  21. package/dist/fs/treeManager.d.ts +84 -0
  22. package/dist/fs/treeManager.d.ts.map +1 -0
  23. package/dist/fs/treeManager.js +365 -0
  24. package/dist/fs/treeManager.js.map +1 -0
  25. package/dist/fs/watcher.d.ts +39 -0
  26. package/dist/fs/watcher.d.ts.map +1 -0
  27. package/dist/fs/watcher.js +120 -0
  28. package/dist/fs/watcher.js.map +1 -0
  29. package/dist/index.d.ts +61 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +349 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/ipc/httpPolling.d.ts +56 -0
  34. package/dist/ipc/httpPolling.d.ts.map +1 -0
  35. package/dist/ipc/httpPolling.js +171 -0
  36. package/dist/ipc/httpPolling.js.map +1 -0
  37. package/dist/ipc/messages.d.ts +112 -0
  38. package/dist/ipc/messages.d.ts.map +1 -0
  39. package/dist/ipc/messages.js +5 -0
  40. package/dist/ipc/messages.js.map +1 -0
  41. package/dist/ipc/server.d.ts +50 -0
  42. package/dist/ipc/server.d.ts.map +1 -0
  43. package/dist/ipc/server.js +168 -0
  44. package/dist/ipc/server.js.map +1 -0
  45. package/dist/pack.d.ts +19 -0
  46. package/dist/pack.d.ts.map +1 -0
  47. package/dist/pack.js +225 -0
  48. package/dist/pack.js.map +1 -0
  49. package/dist/push.d.ts +43 -0
  50. package/dist/push.d.ts.map +1 -0
  51. package/dist/push.js +532 -0
  52. package/dist/push.js.map +1 -0
  53. package/dist/rojo.d.ts +9 -0
  54. package/dist/rojo.d.ts.map +1 -0
  55. package/dist/rojo.js +114 -0
  56. package/dist/rojo.js.map +1 -0
  57. package/dist/snapshot/rojo.d.ts +39 -0
  58. package/dist/snapshot/rojo.d.ts.map +1 -0
  59. package/dist/snapshot/rojo.js +364 -0
  60. package/dist/snapshot/rojo.js.map +1 -0
  61. package/dist/snapshot.d.ts +23 -0
  62. package/dist/snapshot.d.ts.map +1 -0
  63. package/dist/snapshot.js +132 -0
  64. package/dist/snapshot.js.map +1 -0
  65. package/dist/sourcemap/generator.d.ts +78 -0
  66. package/dist/sourcemap/generator.d.ts.map +1 -0
  67. package/dist/sourcemap/generator.js +351 -0
  68. package/dist/sourcemap/generator.js.map +1 -0
  69. package/dist/sourcemap/propertyLoader.d.ts +19 -0
  70. package/dist/sourcemap/propertyLoader.d.ts.map +1 -0
  71. package/dist/sourcemap/propertyLoader.js +131 -0
  72. package/dist/sourcemap/propertyLoader.js.map +1 -0
  73. package/dist/util/id.d.ts +9 -0
  74. package/dist/util/id.d.ts.map +1 -0
  75. package/dist/util/id.js +14 -0
  76. package/dist/util/id.js.map +1 -0
  77. package/dist/util/log.d.ts +13 -0
  78. package/dist/util/log.d.ts.map +1 -0
  79. package/dist/util/log.js +51 -0
  80. package/dist/util/log.js.map +1 -0
  81. package/docs/assets/azul-logo.pdn +0 -0
  82. package/docs/assets/logo-200px.png +0 -0
  83. package/docs/assets/logo.png +0 -0
  84. package/docs/assets/plugin/toolbox.png +0 -0
  85. package/docs/assets/synced.png +0 -0
  86. package/package.json +41 -0
  87. package/plugin/README.md +54 -0
  88. package/plugin/sourcemap.json +264 -0
  89. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/Actor/AzulSync.server.luau +905 -0
  90. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/AzulService.luau +1010 -0
  91. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/Config.luau +29 -0
  92. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/Enums.luau +11 -0
  93. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/CollapsibleTitledSection.luau +214 -0
  94. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/ColorPicker.luau +360 -0
  95. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/CustomTextButton.luau +170 -0
  96. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/DropdownMenu.luau +363 -0
  97. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/HorizontalLine.luau +43 -0
  98. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/ImageButtonWithText.luau +181 -0
  99. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledCheckbox.luau +295 -0
  100. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledColorInputPicker.luau +294 -0
  101. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledMultiChoice.luau +163 -0
  102. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledNumberInput.luau +312 -0
  103. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledRadioButton.luau +55 -0
  104. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledSlider.luau +151 -0
  105. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledTextInput.luau +222 -0
  106. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledToggleButton.luau +73 -0
  107. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/StatefulImageButton.luau +125 -0
  108. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/VerticalScrollingFrame.luau +100 -0
  109. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/VerticalSpacer.luau +35 -0
  110. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/VerticallyScalingListFrame.luau +107 -0
  111. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/GuiUtilities.luau +429 -0
  112. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/RbxGui.luau +4363 -0
  113. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/UI.luau +425 -0
  114. package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/WebSocketClient.luau +161 -0
  115. package/src/build.ts +120 -0
  116. package/src/cli.ts +496 -0
  117. package/src/config.ts +170 -0
  118. package/src/fs/fileWriter.ts +414 -0
  119. package/src/fs/treeManager.ts +458 -0
  120. package/src/fs/watcher.ts +142 -0
  121. package/src/index.ts +450 -0
  122. package/src/ipc/httpPolling.ts +214 -0
  123. package/src/ipc/messages.ts +159 -0
  124. package/src/ipc/server.ts +196 -0
  125. package/src/pack.ts +309 -0
  126. package/src/push.ts +726 -0
  127. package/src/snapshot/rojo.ts +467 -0
  128. package/src/snapshot.ts +161 -0
  129. package/src/sourcemap/generator.ts +504 -0
  130. package/src/sourcemap/propertyLoader.ts +195 -0
  131. package/src/util/id.ts +15 -0
  132. package/src/util/log.ts +94 -0
  133. package/tsconfig.json +24 -0
package/dist/index.js ADDED
@@ -0,0 +1,349 @@
1
+ import path from "node:path";
2
+ import fs from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
+ import * as http from "http";
5
+ import { IPCServer } from "./ipc/server.js";
6
+ import { HttpPollingServer } from "./ipc/httpPolling.js";
7
+ import { TreeManager } from "./fs/treeManager.js";
8
+ import { FileWriter } from "./fs/fileWriter.js";
9
+ import { FileWatcher } from "./fs/watcher.js";
10
+ import { SourcemapGenerator } from "./sourcemap/generator.js";
11
+ import { log } from "./util/log.js";
12
+ import { config, initializeConfig } from "./config.js";
13
+ /**
14
+ * Main orchestrator for the Azul daemon
15
+ */
16
+ export class SyncDaemon {
17
+ ipc;
18
+ httpPolling;
19
+ httpServer;
20
+ tree;
21
+ fileWriter;
22
+ fileWatcher;
23
+ sourcemapGenerator;
24
+ batchDepth = 0; // Tracks nested batch processing
25
+ batchNeedsSourcemapRegen = false; // Defer regen until batch ends
26
+ constructor() {
27
+ this.tree = new TreeManager();
28
+ this.fileWriter = new FileWriter(config.syncDir);
29
+ this.fileWatcher = new FileWatcher();
30
+ this.sourcemapGenerator = new SourcemapGenerator();
31
+ this.httpPolling = new HttpPollingServer();
32
+ // Create HTTP server that handles both WebSocket upgrades and HTTP polling
33
+ this.httpServer = http.createServer((req, res) => {
34
+ const handled = this.httpPolling.handleRequest(req, res);
35
+ if (!handled) {
36
+ res.writeHead(404);
37
+ res.end("Not found");
38
+ }
39
+ });
40
+ this.ipc = new IPCServer(config.port, this.httpServer);
41
+ this.setupHandlers();
42
+ this.httpServer.listen(config.port);
43
+ }
44
+ /**
45
+ * Set up all event handlers
46
+ */
47
+ setupHandlers() {
48
+ // Handle messages from Studio (WebSocket)
49
+ this.ipc.onMessage((message) => this.handleStudioMessage(message));
50
+ // Handle messages from Studio (HTTP polling)
51
+ this.httpPolling.onMessage((message) => this.handleStudioMessage(message));
52
+ // Handle file changes from filesystem
53
+ this.fileWatcher.onChange((filePath, source) => {
54
+ this.handleFileChange(filePath, source);
55
+ });
56
+ }
57
+ /**
58
+ * Handle incoming messages from Studio
59
+ */
60
+ handleStudioMessage(message) {
61
+ if (message.type === "batch") {
62
+ this.batchDepth += 1;
63
+ try {
64
+ for (const payload of message.messages) {
65
+ this.handleStudioMessage(payload);
66
+ }
67
+ }
68
+ finally {
69
+ this.batchDepth -= 1;
70
+ // If any delete in this batch missed its prune, only regenerate once at the end
71
+ if (this.batchDepth === 0 && this.batchNeedsSourcemapRegen) {
72
+ this.regenerateSourcemap();
73
+ this.batchNeedsSourcemapRegen = false;
74
+ }
75
+ }
76
+ return;
77
+ }
78
+ switch (message.type) {
79
+ case "fullSnapshot":
80
+ this.handleFullSnapshot(message.data);
81
+ break;
82
+ case "scriptChanged":
83
+ this.handleScriptChanged(message.data);
84
+ break;
85
+ case "instanceUpdated":
86
+ this.handleInstanceUpdated(message.data);
87
+ break;
88
+ case "deleted":
89
+ this.handleDeleted(message.data);
90
+ break;
91
+ case "ping":
92
+ this.ipc.send({ type: "pong" });
93
+ break;
94
+ case "clientDisconnect":
95
+ log.info("Studio requested to close the connection");
96
+ this.ipc.close();
97
+ break;
98
+ default:
99
+ log.warn("Unknown message type:", message.type);
100
+ }
101
+ }
102
+ /**
103
+ * Handle full snapshot from Studio
104
+ */
105
+ handleFullSnapshot(data) {
106
+ log.info("Received full snapshot from Studio");
107
+ // Update tree
108
+ this.tree.applyFullSnapshot(data);
109
+ // Write all scripts to filesystem
110
+ this.fileWriter.writeTree(this.tree.getAllNodes());
111
+ // Remove any pre-existing files that are no longer mapped (optional)
112
+ this.cleanupOrphanFiles();
113
+ // Start file watching
114
+ this.fileWatcher.watch(this.fileWriter.getBaseDir());
115
+ // Generate sourcemap
116
+ this.regenerateSourcemap();
117
+ // Log statistics
118
+ const stats = this.tree.getStats();
119
+ log.success(`Sync complete: ${stats.scriptNodes} scripts, ${stats.totalNodes} total nodes`);
120
+ }
121
+ /**
122
+ * Handle script source change
123
+ */
124
+ handleScriptChanged(message) {
125
+ const { guid, source, path: instancePath, className } = message;
126
+ // Update tree
127
+ this.tree.updateScriptSource(guid, source);
128
+ // Get or create node
129
+ let node = this.tree.getNode(guid);
130
+ if (!node) {
131
+ // Create new node if it doesn't exist
132
+ this.tree.updateInstance({
133
+ guid,
134
+ className,
135
+ name: instancePath[instancePath.length - 1],
136
+ path: instancePath,
137
+ source,
138
+ });
139
+ node = this.tree.getNode(guid);
140
+ }
141
+ if (node) {
142
+ // Precompute path and suppress watcher before writing to avoid race conditions
143
+ const filePath = this.fileWriter.getFilePath(node);
144
+ this.fileWatcher.suppressNextChange(filePath);
145
+ // Write to filesystem
146
+ this.fileWriter.writeScript(node);
147
+ // Incrementally update sourcemap entry for this script
148
+ this.sourcemapGenerator.upsertSubtree(node, this.tree.getAllNodes(), this.fileWriter.getAllMappings(), config.sourcemapPath, undefined, false);
149
+ }
150
+ }
151
+ /**
152
+ * Handle instance update (rename, move, etc.)
153
+ */
154
+ handleInstanceUpdated(data) {
155
+ const update = this.tree.updateInstance(data);
156
+ const node = update?.node;
157
+ if (!node) {
158
+ return;
159
+ }
160
+ const scriptsToUpdate = new Map();
161
+ if (this.isScriptClass(node.className)) {
162
+ scriptsToUpdate.set(node.guid, node);
163
+ }
164
+ if (update.pathChanged || update.nameChanged || update.parentChanged) {
165
+ for (const child of this.tree.getDescendantScripts(node.guid)) {
166
+ scriptsToUpdate.set(child.guid, child);
167
+ }
168
+ }
169
+ for (const scriptNode of scriptsToUpdate.values()) {
170
+ const filePath = this.fileWriter.getFilePath(scriptNode);
171
+ this.fileWatcher.suppressNextChange(filePath);
172
+ this.fileWriter.writeScript(scriptNode);
173
+ }
174
+ const shouldUpdateSourcemap = update.isNew ||
175
+ update.pathChanged ||
176
+ update.nameChanged ||
177
+ update.parentChanged ||
178
+ this.isScriptClass(node.className);
179
+ if (shouldUpdateSourcemap) {
180
+ this.sourcemapGenerator.upsertSubtree(node, this.tree.getAllNodes(), this.fileWriter.getAllMappings(), config.sourcemapPath, update.prevPath, update.isNew);
181
+ }
182
+ this.fileWriter.cleanupEmptyDirectories();
183
+ }
184
+ /**
185
+ * Handle instance deletion
186
+ */
187
+ handleDeleted(message) {
188
+ const { guid } = message;
189
+ const node = this.tree.getNode(guid);
190
+ // If the node is already gone (e.g., child deletes after parent delete), fall back to full cleanup
191
+ if (!node) {
192
+ log.debug(`Delete ignored for unknown guid: ${guid}`);
193
+ this.fileWriter.deleteScript(guid);
194
+ // this.regenerateSourcemap();
195
+ this.fileWriter.cleanupEmptyDirectories();
196
+ return;
197
+ }
198
+ // Capture all script descendants (and the node itself if script) before we delete the tree nodes
199
+ const scriptsToDelete = [];
200
+ const collectScript = (scriptNode) => {
201
+ const filePath = this.fileWriter.getFilePath(scriptNode);
202
+ scriptsToDelete.push({ guid: scriptNode.guid, filePath });
203
+ };
204
+ if (this.isScriptClass(node.className)) {
205
+ collectScript(node);
206
+ }
207
+ for (const child of this.tree.getDescendantScripts(node.guid)) {
208
+ collectScript(child);
209
+ }
210
+ const pathSegments = node.path;
211
+ // Delete from tree (removes node and descendants)
212
+ this.tree.deleteInstance(guid);
213
+ // Delete files for all affected scripts
214
+ for (const entry of scriptsToDelete) {
215
+ const removed = this.fileWriter.deleteScript(entry.guid);
216
+ if (!removed && entry.filePath) {
217
+ this.fileWriter.deleteFilePath(entry.filePath);
218
+ }
219
+ }
220
+ // Remove subtree from sourcemap
221
+ const outputPath = config.sourcemapPath;
222
+ const pruned = this.sourcemapGenerator.prunePath(pathSegments, outputPath, this.tree.getAllNodes(), this.fileWriter.getAllMappings(), node.className, node.guid);
223
+ // If prune failed to find the path (e.g., sourcemap drift), rebuild once to stay consistent
224
+ if (!pruned) {
225
+ if (this.batchDepth > 0) {
226
+ // Defer regeneration until the batch completes to avoid repeated full rebuilds
227
+ this.batchNeedsSourcemapRegen = true;
228
+ log.debug("Regenerating sourcemap after batched prune miss");
229
+ }
230
+ else {
231
+ log.debug("Regenerating sourcemap due to prune miss");
232
+ this.regenerateSourcemap();
233
+ }
234
+ }
235
+ this.fileWriter.cleanupEmptyDirectories();
236
+ }
237
+ /**
238
+ * Handle file change from filesystem
239
+ */
240
+ handleFileChange(filePath, source) {
241
+ // Find the GUID for this file
242
+ const guid = this.fileWriter.getGuidByPath(filePath);
243
+ if (guid) {
244
+ log.info(`File changed externally: ${path.relative(this.fileWriter.getBaseDir(), filePath)}.`);
245
+ // Update tree
246
+ this.tree.updateScriptSource(guid, source);
247
+ // Send patch to Studio (both WebSocket and HTTP polling clients)
248
+ this.ipc.patchScript(guid, source);
249
+ this.httpPolling.broadcast({ type: "patchScript", guid, source });
250
+ }
251
+ else {
252
+ log.warn(`No mapping found for file: ${filePath}`);
253
+ }
254
+ }
255
+ /**
256
+ * Regenerate the sourcemap
257
+ */
258
+ regenerateSourcemap() {
259
+ // Write sourcemap into the sync directory so Luau-LSP can find it
260
+ const outputPath = config.sourcemapPath;
261
+ this.sourcemapGenerator.generateAndWrite(this.tree.getAllNodes(), this.fileWriter.getAllMappings(), outputPath);
262
+ }
263
+ /**
264
+ * Start the daemon
265
+ */
266
+ start() {
267
+ log.info("🚀 Azul daemon starting...");
268
+ log.info(`Sync directory: ${config.syncDir}`);
269
+ log.info(`HTTP/WebSocket port: ${config.port}`);
270
+ log.info("");
271
+ log.success(`Server listening on http://localhost:${config.port}`);
272
+ log.info("Waiting for Studio connection...");
273
+ }
274
+ /**
275
+ * Stop the daemon
276
+ */
277
+ async stop() {
278
+ log.info("Stopping daemon...");
279
+ await this.fileWatcher.stop();
280
+ this.ipc.close();
281
+ this.httpServer.close();
282
+ log.info("Daemon stopped");
283
+ }
284
+ isScriptClass(className) {
285
+ return (className === "Script" ||
286
+ className === "LocalScript" ||
287
+ className === "ModuleScript");
288
+ }
289
+ /**
290
+ * Delete files under syncDir that are not mapped to any instance (opt-in).
291
+ */
292
+ cleanupOrphanFiles() {
293
+ if (!config.deleteOrphansOnConnect) {
294
+ return;
295
+ }
296
+ const baseDir = this.fileWriter.getBaseDir();
297
+ const mapped = new Set();
298
+ for (const mapping of this.fileWriter.getAllMappings().values()) {
299
+ mapped.add(path.resolve(mapping.filePath));
300
+ }
301
+ let removedFiles = [];
302
+ const walk = (dir) => {
303
+ if (!fs.existsSync(dir))
304
+ return;
305
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
306
+ for (const entry of entries) {
307
+ const fullPath = path.join(dir, entry.name);
308
+ if (entry.isDirectory()) {
309
+ walk(fullPath);
310
+ }
311
+ else {
312
+ if (!mapped.has(path.resolve(fullPath))) {
313
+ try {
314
+ fs.unlinkSync(fullPath);
315
+ removedFiles.push(entry.name);
316
+ }
317
+ catch (error) {
318
+ log.warn("Failed to delete orphan file:", fullPath, error);
319
+ }
320
+ }
321
+ }
322
+ }
323
+ };
324
+ walk(baseDir);
325
+ if (removedFiles.length > 0) {
326
+ this.fileWriter.cleanupEmptyDirectories();
327
+ log.success(`Removed ${removedFiles.length} orphan file(s) from sync directory (${removedFiles.join(", ")})`);
328
+ }
329
+ }
330
+ }
331
+ // Allow direct execution (`node dist/index.js`) while preventing side effects when imported by the CLI
332
+ const isDirectRun = process.argv[1] &&
333
+ fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);
334
+ if (isDirectRun) {
335
+ initializeConfig();
336
+ const daemon = new SyncDaemon();
337
+ daemon.start();
338
+ // Handle graceful shutdown
339
+ process.on("SIGINT", async () => {
340
+ console.log("\n");
341
+ await daemon.stop();
342
+ process.exit(0);
343
+ });
344
+ process.on("SIGTERM", async () => {
345
+ await daemon.stop();
346
+ process.exit(0);
347
+ });
348
+ }
349
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * HTTP endpoints for plugin polling compatibility
3
+ */
4
+ import { IncomingMessage, ServerResponse } from "http";
5
+ /**
6
+ * Manages HTTP polling for Roblox Studio plugin compatibility
7
+ */
8
+ export declare class HttpPollingServer {
9
+ private clients;
10
+ private messageHandler;
11
+ /**
12
+ * Handle HTTP request
13
+ */
14
+ handleRequest(req: IncomingMessage, res: ServerResponse): boolean;
15
+ /**
16
+ * Handle connect request
17
+ */
18
+ private handleConnect;
19
+ /**
20
+ * Handle send request
21
+ */
22
+ private handleSend;
23
+ /**
24
+ * Handle poll request
25
+ */
26
+ private handlePoll;
27
+ /**
28
+ * Handle disconnect request
29
+ */
30
+ private handleDisconnect;
31
+ /**
32
+ * Send message to a specific client
33
+ */
34
+ sendToClient(clientId: string, message: any): boolean;
35
+ /**
36
+ * Broadcast message to all clients
37
+ */
38
+ broadcast(message: any): void;
39
+ /**
40
+ * Set message handler
41
+ */
42
+ onMessage(handler: (message: any, clientId: string) => void): void;
43
+ /**
44
+ * Clean up stale clients
45
+ */
46
+ cleanupStaleClients(timeoutMs?: number): void;
47
+ /**
48
+ * Generate unique client ID
49
+ */
50
+ private generateClientId;
51
+ /**
52
+ * Get active client count
53
+ */
54
+ getClientCount(): number;
55
+ }
56
+ //# sourceMappingURL=httpPolling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"httpPolling.d.ts","sourceRoot":"","sources":["../../src/ipc/httpPolling.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AASvD;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAyC;IACxD,OAAO,CAAC,cAAc,CACf;IAEP;;OAEG;IACI,aAAa,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO;IA4BxE;;OAEG;IACH,OAAO,CAAC,aAAa;IAgBrB;;OAEG;IACH,OAAO,CAAC,UAAU;IA2BlB;;OAEG;IACH,OAAO,CAAC,UAAU;IAuBlB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA4BxB;;OAEG;IACI,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO;IAU5D;;OAEG;IACI,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAMpC;;OAEG;IACI,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIzE;;OAEG;IACI,mBAAmB,CAAC,SAAS,GAAE,MAAc,GAAG,IAAI;IAU3D;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;OAEG;IACI,cAAc,IAAI,MAAM;CAGhC"}
@@ -0,0 +1,171 @@
1
+ /**
2
+ * HTTP endpoints for plugin polling compatibility
3
+ */
4
+ import { log } from "../util/log.js";
5
+ /**
6
+ * Manages HTTP polling for Roblox Studio plugin compatibility
7
+ */
8
+ export class HttpPollingServer {
9
+ clients = new Map();
10
+ messageHandler = null;
11
+ /**
12
+ * Handle HTTP request
13
+ */
14
+ handleRequest(req, res) {
15
+ const url = new URL(req.url || "", `http://${req.headers.host}`);
16
+ // Enable CORS
17
+ res.setHeader("Access-Control-Allow-Origin", "*");
18
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
19
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type");
20
+ if (req.method === "OPTIONS") {
21
+ res.writeHead(200);
22
+ res.end();
23
+ return true;
24
+ }
25
+ switch (url.pathname) {
26
+ case "/connect":
27
+ return this.handleConnect(req, res);
28
+ case "/send":
29
+ return this.handleSend(req, res);
30
+ case "/poll":
31
+ return this.handlePoll(req, res, url);
32
+ case "/disconnect":
33
+ return this.handleDisconnect(req, res);
34
+ default:
35
+ return false;
36
+ }
37
+ }
38
+ /**
39
+ * Handle connect request
40
+ */
41
+ handleConnect(_req, res) {
42
+ const clientId = this.generateClientId();
43
+ this.clients.set(clientId, {
44
+ id: clientId,
45
+ messageQueue: [],
46
+ lastPoll: Date.now(),
47
+ });
48
+ log.info(`HTTP client connected: ${clientId}`);
49
+ res.writeHead(200, { "Content-Type": "application/json" });
50
+ res.end(JSON.stringify({ clientId }));
51
+ return true;
52
+ }
53
+ /**
54
+ * Handle send request
55
+ */
56
+ handleSend(req, res) {
57
+ let body = "";
58
+ req.on("data", (chunk) => {
59
+ body += chunk.toString();
60
+ });
61
+ req.on("end", () => {
62
+ try {
63
+ const data = JSON.parse(body);
64
+ const { clientId, message } = data;
65
+ if (this.messageHandler) {
66
+ this.messageHandler(message, clientId);
67
+ }
68
+ res.writeHead(200, { "Content-Type": "application/json" });
69
+ res.end(JSON.stringify({ success: true }));
70
+ }
71
+ catch (error) {
72
+ res.writeHead(400, { "Content-Type": "application/json" });
73
+ res.end(JSON.stringify({ error: "Invalid JSON" }));
74
+ }
75
+ });
76
+ return true;
77
+ }
78
+ /**
79
+ * Handle poll request
80
+ */
81
+ handlePoll(_req, res, url) {
82
+ const clientId = url.searchParams.get("clientId");
83
+ if (!clientId || !this.clients.has(clientId)) {
84
+ res.writeHead(404, { "Content-Type": "application/json" });
85
+ res.end(JSON.stringify({ error: "Client not found" }));
86
+ return true;
87
+ }
88
+ const client = this.clients.get(clientId);
89
+ client.lastPoll = Date.now();
90
+ const messages = client.messageQueue.splice(0); // Take all messages
91
+ res.writeHead(200, { "Content-Type": "application/json" });
92
+ res.end(JSON.stringify(messages));
93
+ return true;
94
+ }
95
+ /**
96
+ * Handle disconnect request
97
+ */
98
+ handleDisconnect(req, res) {
99
+ let body = "";
100
+ req.on("data", (chunk) => {
101
+ body += chunk.toString();
102
+ });
103
+ req.on("end", () => {
104
+ try {
105
+ const data = JSON.parse(body);
106
+ const { clientId } = data;
107
+ if (clientId && this.clients.has(clientId)) {
108
+ this.clients.delete(clientId);
109
+ log.info(`HTTP client disconnected: ${clientId}`);
110
+ }
111
+ res.writeHead(200, { "Content-Type": "application/json" });
112
+ res.end(JSON.stringify({ success: true }));
113
+ }
114
+ catch (error) {
115
+ res.writeHead(400, { "Content-Type": "application/json" });
116
+ res.end(JSON.stringify({ error: "Invalid JSON" }));
117
+ }
118
+ });
119
+ return true;
120
+ }
121
+ /**
122
+ * Send message to a specific client
123
+ */
124
+ sendToClient(clientId, message) {
125
+ const client = this.clients.get(clientId);
126
+ if (!client) {
127
+ return false;
128
+ }
129
+ client.messageQueue.push(message);
130
+ return true;
131
+ }
132
+ /**
133
+ * Broadcast message to all clients
134
+ */
135
+ broadcast(message) {
136
+ for (const client of this.clients.values()) {
137
+ client.messageQueue.push(message);
138
+ }
139
+ }
140
+ /**
141
+ * Set message handler
142
+ */
143
+ onMessage(handler) {
144
+ this.messageHandler = handler;
145
+ }
146
+ /**
147
+ * Clean up stale clients
148
+ */
149
+ cleanupStaleClients(timeoutMs = 60000) {
150
+ const now = Date.now();
151
+ for (const [id, client] of this.clients.entries()) {
152
+ if (now - client.lastPoll > timeoutMs) {
153
+ this.clients.delete(id);
154
+ log.info(`Removed stale HTTP client: ${id}`);
155
+ }
156
+ }
157
+ }
158
+ /**
159
+ * Generate unique client ID
160
+ */
161
+ generateClientId() {
162
+ return `client_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
163
+ }
164
+ /**
165
+ * Get active client count
166
+ */
167
+ getClientCount() {
168
+ return this.clients.size;
169
+ }
170
+ }
171
+ //# sourceMappingURL=httpPolling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"httpPolling.js","sourceRoot":"","sources":["../../src/ipc/httpPolling.ts"],"names":[],"mappings":"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"}