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
@@ -0,0 +1,365 @@
1
+ import { log } from "../util/log.js";
2
+ /**
3
+ * Manages the in-memory representation of Studio's DataModel
4
+ */
5
+ export class TreeManager {
6
+ nodes = new Map();
7
+ pathIndex = new Map(); // pathKey → TreeNodes (same name siblings supported)
8
+ root = null;
9
+ pathKey(path) {
10
+ return path.join("\u0000");
11
+ }
12
+ addToPathIndex(node) {
13
+ const key = this.pathKey(node.path);
14
+ const bucket = this.pathIndex.get(key) ?? new Set();
15
+ bucket.add(node);
16
+ this.pathIndex.set(key, bucket);
17
+ }
18
+ removeFromPathIndex(node) {
19
+ const key = this.pathKey(node.path);
20
+ const bucket = this.pathIndex.get(key);
21
+ if (!bucket)
22
+ return;
23
+ bucket.delete(node);
24
+ if (bucket.size === 0) {
25
+ this.pathIndex.delete(key);
26
+ }
27
+ }
28
+ registerSubtree(node) {
29
+ const stack = [node];
30
+ while (stack.length > 0) {
31
+ const current = stack.pop();
32
+ this.addToPathIndex(current);
33
+ for (const child of current.children.values()) {
34
+ stack.push(child);
35
+ }
36
+ }
37
+ }
38
+ unregisterSubtree(node) {
39
+ const stack = [node];
40
+ while (stack.length > 0) {
41
+ const current = stack.pop();
42
+ this.removeFromPathIndex(current);
43
+ for (const child of current.children.values()) {
44
+ stack.push(child);
45
+ }
46
+ }
47
+ }
48
+ updateInstance(instance) {
49
+ const existing = this.nodes.get(instance.guid);
50
+ const hasParentHint = instance.parentGuid !== undefined;
51
+ const incomingParentGuid = hasParentHint
52
+ ? (instance.parentGuid ?? null)
53
+ : null;
54
+ if (existing) {
55
+ const prevPath = [...existing.path];
56
+ const prevName = existing.name;
57
+ const pathChanged = !this.pathsEqual(existing.path, instance.path);
58
+ const nameChanged = existing.name !== instance.name;
59
+ const currentParentGuid = existing.parent?.guid ?? existing.parentGuid ?? null;
60
+ const nextParentGuid = hasParentHint
61
+ ? incomingParentGuid
62
+ : currentParentGuid;
63
+ const parentChanged = hasParentHint && nextParentGuid !== currentParentGuid;
64
+ const nextSource = instance.source !== undefined ? instance.source : existing.source;
65
+ if (pathChanged) {
66
+ this.unregisterSubtree(existing);
67
+ }
68
+ existing.className = instance.className;
69
+ existing.name = instance.name;
70
+ existing.path = instance.path;
71
+ existing.parentGuid = nextParentGuid;
72
+ existing.source = nextSource;
73
+ if (pathChanged || nameChanged || parentChanged) {
74
+ this.reparentNode(existing, instance.path, nextParentGuid);
75
+ this.recalculateChildPaths(existing);
76
+ this.registerSubtree(existing);
77
+ }
78
+ log.script(`Updated instance: ${instance.path.join("/")}`, "updated");
79
+ return {
80
+ node: existing,
81
+ pathChanged,
82
+ nameChanged,
83
+ parentChanged,
84
+ isNew: false,
85
+ prevPath,
86
+ prevName,
87
+ };
88
+ }
89
+ const node = {
90
+ guid: instance.guid,
91
+ className: instance.className,
92
+ name: instance.name,
93
+ path: instance.path,
94
+ parentGuid: incomingParentGuid,
95
+ source: instance.source,
96
+ children: new Map(),
97
+ };
98
+ this.nodes.set(instance.guid, node);
99
+ this.reparentNode(node, instance.path, incomingParentGuid);
100
+ this.recalculateChildPaths(node);
101
+ this.registerSubtree(node);
102
+ log.script(`Created instance: ${instance.path.join("/")}`, "created");
103
+ return {
104
+ node,
105
+ pathChanged: false,
106
+ nameChanged: false,
107
+ parentChanged: false,
108
+ isNew: true,
109
+ };
110
+ }
111
+ /**
112
+ * Process a full snapshot from Studio
113
+ */
114
+ applyFullSnapshot(instances) {
115
+ log.info(`Processing full snapshot: ${instances.length} instances`);
116
+ // Clear existing tree
117
+ this.nodes.clear();
118
+ this.pathIndex.clear();
119
+ this.root = null;
120
+ // First pass: create all nodes
121
+ for (const instance of instances) {
122
+ const node = {
123
+ guid: instance.guid,
124
+ className: instance.className,
125
+ name: instance.name,
126
+ path: instance.path,
127
+ parentGuid: instance.parentGuid ?? null,
128
+ source: instance.source,
129
+ children: new Map(),
130
+ };
131
+ this.nodes.set(instance.guid, node);
132
+ this.addToPathIndex(node);
133
+ log.debug(`Created node: ${instance.path.join("/")}`);
134
+ }
135
+ // Second pass: build hierarchy
136
+ for (const instance of instances) {
137
+ const node = this.nodes.get(instance.guid);
138
+ if (!node)
139
+ continue;
140
+ if (instance.path.length === 1) {
141
+ // This is a root service
142
+ if (!this.root) {
143
+ this.root = {
144
+ guid: "root",
145
+ className: "DataModel",
146
+ name: "game",
147
+ path: [],
148
+ parentGuid: null,
149
+ children: new Map(),
150
+ };
151
+ this.nodes.set("root", this.root);
152
+ this.addToPathIndex(this.root);
153
+ }
154
+ this.root.children.set(node.guid, node);
155
+ node.parent = this.root;
156
+ node.parentGuid = this.root.guid;
157
+ log.debug(`Assigned root parent for: ${instance.path.join("/")}`);
158
+ }
159
+ else {
160
+ // Find parent by matching path
161
+ const parentPath = instance.path.slice(0, -1);
162
+ const explicitParentGuid = instance.parentGuid ?? null;
163
+ let parent;
164
+ if (explicitParentGuid) {
165
+ parent = this.nodes.get(explicitParentGuid);
166
+ }
167
+ if (!parent) {
168
+ parent = this.findNodeByPath(parentPath);
169
+ }
170
+ if (parent) {
171
+ parent.children.set(node.guid, node);
172
+ node.parent = parent;
173
+ node.parentGuid = parent.guid;
174
+ log.debug(`Assigned parent for: ${instance.path.join("/")}`);
175
+ }
176
+ else {
177
+ log.warn(`Parent not found for ${instance.path.join("/")}`);
178
+ }
179
+ }
180
+ }
181
+ log.success(`Tree built: ${this.nodes.size} nodes`);
182
+ }
183
+ /**
184
+ * Update child paths iteratively
185
+ */
186
+ recalculateChildPaths(node) {
187
+ const queue = [...node.children.values()];
188
+ while (queue.length > 0) {
189
+ const child = queue.shift();
190
+ child.path = [...child.parent.path, child.name];
191
+ for (const grandchild of child.children.values()) {
192
+ queue.push(grandchild);
193
+ }
194
+ }
195
+ }
196
+ getDescendantScripts(guid) {
197
+ const start = this.nodes.get(guid);
198
+ if (!start) {
199
+ return [];
200
+ }
201
+ const scripts = [];
202
+ const stack = [...start.children.values()];
203
+ while (stack.length > 0) {
204
+ const node = stack.pop();
205
+ if (this.isScriptNode(node)) {
206
+ scripts.push(node);
207
+ }
208
+ for (const child of node.children.values()) {
209
+ stack.push(child);
210
+ }
211
+ }
212
+ return scripts;
213
+ }
214
+ isScriptNode(node) {
215
+ return (node.className === "Script" ||
216
+ node.className === "LocalScript" ||
217
+ node.className === "ModuleScript");
218
+ }
219
+ pathsEqual(a, b) {
220
+ if (a.length !== b.length)
221
+ return false;
222
+ return a.every((segment, idx) => segment === b[idx]);
223
+ }
224
+ /**
225
+ * Delete an instance by GUID
226
+ */
227
+ deleteInstance(guid) {
228
+ const node = this.nodes.get(guid);
229
+ if (!node) {
230
+ log.debug(`Delete ignored for missing node: ${guid}`);
231
+ return null;
232
+ }
233
+ // Detach from parent first so no one references this subtree
234
+ if (node.parent) {
235
+ node.parent.children.delete(guid);
236
+ }
237
+ // Iterative delete to avoid repeated recursion work on large subtrees
238
+ const stack = [node];
239
+ while (stack.length > 0) {
240
+ const current = stack.pop();
241
+ for (const child of current.children.values()) {
242
+ stack.push(child);
243
+ }
244
+ this.removeFromPathIndex(current);
245
+ this.nodes.delete(current.guid);
246
+ // Break references to help GC and prevent accidental reuse
247
+ current.children.clear();
248
+ current.parent = undefined;
249
+ }
250
+ log.script(`Deleted instance: ${node.path.join("/")}`, "deleted");
251
+ return node;
252
+ }
253
+ /**
254
+ * Update script source only
255
+ */
256
+ updateScriptSource(guid, source) {
257
+ const node = this.nodes.get(guid);
258
+ if (node) {
259
+ node.source = source;
260
+ log.debug(`Updated script source: ${node.path.join("/")}`);
261
+ }
262
+ else {
263
+ log.warn(`Script not found for GUID: ${guid}`);
264
+ }
265
+ }
266
+ /**
267
+ * Get a node by GUID
268
+ */
269
+ getNode(guid) {
270
+ return this.nodes.get(guid);
271
+ }
272
+ /**
273
+ * Get all nodes
274
+ */
275
+ getAllNodes() {
276
+ return this.nodes;
277
+ }
278
+ /**
279
+ * Get all script nodes
280
+ */
281
+ getScriptNodes() {
282
+ return Array.from(this.nodes.values()).filter((node) => this.isScriptNode(node));
283
+ }
284
+ /**
285
+ * Find a node by its path
286
+ */
287
+ findNodeByPath(path) {
288
+ const bucket = this.pathIndex.get(this.pathKey(path));
289
+ if (!bucket || bucket.size === 0) {
290
+ return undefined;
291
+ }
292
+ if (bucket.size === 1) {
293
+ return bucket.values().next().value;
294
+ }
295
+ // Ambiguous path (same-name siblings); caller should use parent GUIDs instead
296
+ log.debug(`Multiple nodes share path ${path.join("/")}, skipping path lookup`);
297
+ return undefined;
298
+ }
299
+ /**
300
+ * Re-parent a node based on its path
301
+ */
302
+ reparentNode(node, path, parentGuid) {
303
+ // Remove from old parent
304
+ if (node.parent) {
305
+ node.parent.children.delete(node.guid);
306
+ }
307
+ // Find new parent (prefer explicit parent GUID when present)
308
+ let parent;
309
+ if (parentGuid) {
310
+ parent = this.nodes.get(parentGuid);
311
+ }
312
+ if (!parent) {
313
+ if (path.length === 1) {
314
+ // Root service
315
+ if (!this.root) {
316
+ this.root = {
317
+ guid: "root",
318
+ className: "DataModel",
319
+ name: "game",
320
+ path: [],
321
+ parentGuid: null,
322
+ children: new Map(),
323
+ };
324
+ this.nodes.set("root", this.root);
325
+ this.addToPathIndex(this.root);
326
+ }
327
+ parent = this.root;
328
+ }
329
+ else {
330
+ const parentPath = path.slice(0, -1);
331
+ parent = this.findNodeByPath(parentPath);
332
+ }
333
+ }
334
+ if (parent) {
335
+ parent.children.set(node.guid, node);
336
+ node.parent = parent;
337
+ node.parentGuid = parent.guid;
338
+ }
339
+ else {
340
+ log.debug(`Parent not found for re-parenting: ${path.join("/")}`);
341
+ }
342
+ }
343
+ /**
344
+ * Get tree statistics
345
+ */
346
+ getStats() {
347
+ let scriptCount = 0;
348
+ let maxDepth = 0;
349
+ for (const node of this.nodes.values()) {
350
+ if (this.isScriptNode(node)) {
351
+ scriptCount += 1;
352
+ }
353
+ const depth = node.path.length;
354
+ if (depth > maxDepth) {
355
+ maxDepth = depth;
356
+ }
357
+ }
358
+ return {
359
+ totalNodes: this.nodes.size,
360
+ scriptNodes: scriptCount,
361
+ maxDepth,
362
+ };
363
+ }
364
+ }
365
+ //# sourceMappingURL=treeManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"treeManager.js","sourceRoot":"","sources":["../../src/fs/treeManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ export type FileChangeHandler = (filePath: string, source: string) => void;
2
+ /**
3
+ * Watches the filesystem for changes and notifies handlers
4
+ */
5
+ export declare class FileWatcher {
6
+ private watcher;
7
+ private changeHandler;
8
+ private debounceTimers;
9
+ private suppressedUntil;
10
+ /**
11
+ * Start watching a directory
12
+ */
13
+ watch(directory: string): void;
14
+ /**
15
+ * Handle a file change with debouncing
16
+ */
17
+ private handleFileChange;
18
+ /**
19
+ * Process a file change after debouncing
20
+ */
21
+ private processFileChange;
22
+ /**
23
+ * Check if a file is a script file
24
+ */
25
+ private isScriptFile;
26
+ /**
27
+ * Register a handler for file changes
28
+ */
29
+ onChange(handler: FileChangeHandler): void;
30
+ /**
31
+ * Suppress the next change event for a specific file path (normalized)
32
+ */
33
+ suppressNextChange(filePath: string): void;
34
+ /**
35
+ * Stop watching
36
+ */
37
+ stop(): Promise<void>;
38
+ }
39
+ //# sourceMappingURL=watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../../src/fs/watcher.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,iBAAiB,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAE3E;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,cAAc,CAA0C;IAChE,OAAO,CAAC,eAAe,CAAkC;IAEzD;;OAEG;IACI,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IA8BrC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAgBxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA8BzB;;OAEG;IACH,OAAO,CAAC,YAAY;IAIpB;;OAEG;IACI,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAIjD;;OAEG;IACI,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAMjD;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAanC"}
@@ -0,0 +1,120 @@
1
+ import * as chokidar from "chokidar";
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+ import { log } from "../util/log.js";
5
+ import { config } from "../config.js";
6
+ /**
7
+ * Watches the filesystem for changes and notifies handlers
8
+ */
9
+ export class FileWatcher {
10
+ watcher = null;
11
+ changeHandler = null;
12
+ debounceTimers = new Map();
13
+ suppressedUntil = new Map();
14
+ /**
15
+ * Start watching a directory
16
+ */
17
+ watch(directory) {
18
+ if (this.watcher) {
19
+ log.warn("Watcher already running, stopping it first");
20
+ this.stop();
21
+ }
22
+ log.info(`Starting file watcher on: ${directory}`);
23
+ this.watcher = chokidar.watch(directory, {
24
+ persistent: true,
25
+ ignoreInitial: true,
26
+ awaitWriteFinish: {
27
+ stabilityThreshold: 100,
28
+ pollInterval: 50,
29
+ },
30
+ });
31
+ this.watcher.on("change", (filePath) => {
32
+ this.handleFileChange(filePath);
33
+ });
34
+ this.watcher.on("error", (error) => {
35
+ log.error("File watcher error:", error);
36
+ });
37
+ this.watcher.on("ready", () => {
38
+ log.success("File watcher ready");
39
+ });
40
+ }
41
+ /**
42
+ * Handle a file change with debouncing
43
+ */
44
+ handleFileChange(filePath) {
45
+ // Clear existing timer for this file
46
+ const existingTimer = this.debounceTimers.get(filePath);
47
+ if (existingTimer) {
48
+ clearTimeout(existingTimer);
49
+ }
50
+ // Set new debounced timer
51
+ const timer = setTimeout(() => {
52
+ this.processFileChange(filePath);
53
+ this.debounceTimers.delete(filePath);
54
+ }, config.fileWatchDebounce);
55
+ this.debounceTimers.set(filePath, timer);
56
+ }
57
+ /**
58
+ * Process a file change after debouncing
59
+ */
60
+ processFileChange(filePath) {
61
+ const normalizedPath = path.resolve(filePath);
62
+ // Skip if this change was produced by a Studio-originated write
63
+ const now = Date.now();
64
+ const suppressUntil = this.suppressedUntil.get(normalizedPath);
65
+ if (suppressUntil && suppressUntil > now) {
66
+ log.debug(`File change suppressed (Studio-originated): ${normalizedPath}`);
67
+ return;
68
+ }
69
+ // Only process script files
70
+ if (!this.isScriptFile(filePath)) {
71
+ return;
72
+ }
73
+ try {
74
+ const source = fs.readFileSync(filePath, "utf-8");
75
+ log.debug(`File changed: ${normalizedPath}`);
76
+ if (this.changeHandler) {
77
+ this.changeHandler(normalizedPath, source);
78
+ }
79
+ }
80
+ catch (error) {
81
+ log.error(`Failed to read changed file ${filePath}:`, error);
82
+ }
83
+ }
84
+ /**
85
+ * Check if a file is a script file
86
+ */
87
+ isScriptFile(filePath) {
88
+ return filePath.endsWith(".lua") || filePath.endsWith(".luau");
89
+ }
90
+ /**
91
+ * Register a handler for file changes
92
+ */
93
+ onChange(handler) {
94
+ this.changeHandler = handler;
95
+ }
96
+ /**
97
+ * Suppress the next change event for a specific file path (normalized)
98
+ */
99
+ suppressNextChange(filePath) {
100
+ const normalizedPath = path.resolve(filePath);
101
+ const until = Date.now() + 1000; // 1s window to absorb duplicate events
102
+ this.suppressedUntil.set(normalizedPath, until);
103
+ }
104
+ /**
105
+ * Stop watching
106
+ */
107
+ async stop() {
108
+ if (this.watcher) {
109
+ await this.watcher.close();
110
+ this.watcher = null;
111
+ log.info("File watcher stopped");
112
+ }
113
+ // Clear all pending timers
114
+ for (const timer of this.debounceTimers.values()) {
115
+ clearTimeout(timer);
116
+ }
117
+ this.debounceTimers.clear();
118
+ }
119
+ }
120
+ //# sourceMappingURL=watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../src/fs/watcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Main orchestrator for the Azul daemon
3
+ */
4
+ export declare class SyncDaemon {
5
+ private ipc;
6
+ private httpPolling;
7
+ private httpServer;
8
+ private tree;
9
+ private fileWriter;
10
+ private fileWatcher;
11
+ private sourcemapGenerator;
12
+ private batchDepth;
13
+ private batchNeedsSourcemapRegen;
14
+ constructor();
15
+ /**
16
+ * Set up all event handlers
17
+ */
18
+ private setupHandlers;
19
+ /**
20
+ * Handle incoming messages from Studio
21
+ */
22
+ private handleStudioMessage;
23
+ /**
24
+ * Handle full snapshot from Studio
25
+ */
26
+ private handleFullSnapshot;
27
+ /**
28
+ * Handle script source change
29
+ */
30
+ private handleScriptChanged;
31
+ /**
32
+ * Handle instance update (rename, move, etc.)
33
+ */
34
+ private handleInstanceUpdated;
35
+ /**
36
+ * Handle instance deletion
37
+ */
38
+ private handleDeleted;
39
+ /**
40
+ * Handle file change from filesystem
41
+ */
42
+ private handleFileChange;
43
+ /**
44
+ * Regenerate the sourcemap
45
+ */
46
+ private regenerateSourcemap;
47
+ /**
48
+ * Start the daemon
49
+ */
50
+ start(): void;
51
+ /**
52
+ * Stop the daemon
53
+ */
54
+ stop(): Promise<void>;
55
+ private isScriptClass;
56
+ /**
57
+ * Delete files under syncDir that are not mapped to any instance (opt-in).
58
+ */
59
+ private cleanupOrphanFiles;
60
+ }
61
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,GAAG,CAAY;IACvB,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,UAAU,CAAc;IAChC,OAAO,CAAC,IAAI,CAAc;IAC1B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,wBAAwB,CAAS;;IAwBzC;;OAEG;IACH,OAAO,CAAC,aAAa;IAarB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAkD3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAyB1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA6C3B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA+C7B;;OAEG;IACH,OAAO,CAAC,aAAa;IAkErB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAoBxB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAU3B;;OAEG;IACI,KAAK,IAAI,IAAI;IASpB;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQlC,OAAO,CAAC,aAAa;IAQrB;;OAEG;IACH,OAAO,CAAC,kBAAkB;CA0C3B"}