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.
- package/.gitattributes +1 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/README.md +142 -0
- package/dist/build.d.ts +19 -0
- package/dist/build.d.ts.map +1 -0
- package/dist/build.js +92 -0
- package/dist/build.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +397 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +26 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +105 -0
- package/dist/config.js.map +1 -0
- package/dist/fs/fileWriter.d.ts +100 -0
- package/dist/fs/fileWriter.d.ts.map +1 -0
- package/dist/fs/fileWriter.js +342 -0
- package/dist/fs/fileWriter.js.map +1 -0
- package/dist/fs/treeManager.d.ts +84 -0
- package/dist/fs/treeManager.d.ts.map +1 -0
- package/dist/fs/treeManager.js +365 -0
- package/dist/fs/treeManager.js.map +1 -0
- package/dist/fs/watcher.d.ts +39 -0
- package/dist/fs/watcher.d.ts.map +1 -0
- package/dist/fs/watcher.js +120 -0
- package/dist/fs/watcher.js.map +1 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +349 -0
- package/dist/index.js.map +1 -0
- package/dist/ipc/httpPolling.d.ts +56 -0
- package/dist/ipc/httpPolling.d.ts.map +1 -0
- package/dist/ipc/httpPolling.js +171 -0
- package/dist/ipc/httpPolling.js.map +1 -0
- package/dist/ipc/messages.d.ts +112 -0
- package/dist/ipc/messages.d.ts.map +1 -0
- package/dist/ipc/messages.js +5 -0
- package/dist/ipc/messages.js.map +1 -0
- package/dist/ipc/server.d.ts +50 -0
- package/dist/ipc/server.d.ts.map +1 -0
- package/dist/ipc/server.js +168 -0
- package/dist/ipc/server.js.map +1 -0
- package/dist/pack.d.ts +19 -0
- package/dist/pack.d.ts.map +1 -0
- package/dist/pack.js +225 -0
- package/dist/pack.js.map +1 -0
- package/dist/push.d.ts +43 -0
- package/dist/push.d.ts.map +1 -0
- package/dist/push.js +532 -0
- package/dist/push.js.map +1 -0
- package/dist/rojo.d.ts +9 -0
- package/dist/rojo.d.ts.map +1 -0
- package/dist/rojo.js +114 -0
- package/dist/rojo.js.map +1 -0
- package/dist/snapshot/rojo.d.ts +39 -0
- package/dist/snapshot/rojo.d.ts.map +1 -0
- package/dist/snapshot/rojo.js +364 -0
- package/dist/snapshot/rojo.js.map +1 -0
- package/dist/snapshot.d.ts +23 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +132 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/sourcemap/generator.d.ts +78 -0
- package/dist/sourcemap/generator.d.ts.map +1 -0
- package/dist/sourcemap/generator.js +351 -0
- package/dist/sourcemap/generator.js.map +1 -0
- package/dist/sourcemap/propertyLoader.d.ts +19 -0
- package/dist/sourcemap/propertyLoader.d.ts.map +1 -0
- package/dist/sourcemap/propertyLoader.js +131 -0
- package/dist/sourcemap/propertyLoader.js.map +1 -0
- package/dist/util/id.d.ts +9 -0
- package/dist/util/id.d.ts.map +1 -0
- package/dist/util/id.js +14 -0
- package/dist/util/id.js.map +1 -0
- package/dist/util/log.d.ts +13 -0
- package/dist/util/log.d.ts.map +1 -0
- package/dist/util/log.js +51 -0
- package/dist/util/log.js.map +1 -0
- package/docs/assets/azul-logo.pdn +0 -0
- package/docs/assets/logo-200px.png +0 -0
- package/docs/assets/logo.png +0 -0
- package/docs/assets/plugin/toolbox.png +0 -0
- package/docs/assets/synced.png +0 -0
- package/package.json +41 -0
- package/plugin/README.md +54 -0
- package/plugin/sourcemap.json +264 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/Actor/AzulSync.server.luau +905 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/AzulService.luau +1010 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/Config.luau +29 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/Enums.luau +11 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/CollapsibleTitledSection.luau +214 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/ColorPicker.luau +360 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/CustomTextButton.luau +170 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/DropdownMenu.luau +363 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/HorizontalLine.luau +43 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/ImageButtonWithText.luau +181 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledCheckbox.luau +295 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledColorInputPicker.luau +294 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledMultiChoice.luau +163 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledNumberInput.luau +312 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledRadioButton.luau +55 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledSlider.luau +151 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledTextInput.luau +222 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/LabeledToggleButton.luau +73 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/StatefulImageButton.luau +125 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/VerticalScrollingFrame.luau +100 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/VerticalSpacer.luau +35 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/Components/VerticallyScalingListFrame.luau +107 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/GuiUtilities.luau +429 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/StudioWidgets/RbxGui.luau +4363 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/UI.luau +425 -0
- package/plugin/sync/ReplicatedFirst/AzulCompanionPlugin/WebSocketClient.luau +161 -0
- package/src/build.ts +120 -0
- package/src/cli.ts +496 -0
- package/src/config.ts +170 -0
- package/src/fs/fileWriter.ts +414 -0
- package/src/fs/treeManager.ts +458 -0
- package/src/fs/watcher.ts +142 -0
- package/src/index.ts +450 -0
- package/src/ipc/httpPolling.ts +214 -0
- package/src/ipc/messages.ts +159 -0
- package/src/ipc/server.ts +196 -0
- package/src/pack.ts +309 -0
- package/src/push.ts +726 -0
- package/src/snapshot/rojo.ts +467 -0
- package/src/snapshot.ts +161 -0
- package/src/sourcemap/generator.ts +504 -0
- package/src/sourcemap/propertyLoader.ts +195 -0
- package/src/util/id.ts +15 -0
- package/src/util/log.ts +94 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { config } from "../config.js";
|
|
4
|
+
import { log } from "../util/log.js";
|
|
5
|
+
/**
|
|
6
|
+
* Handles writing the virtual tree to the filesystem
|
|
7
|
+
*/
|
|
8
|
+
export class FileWriter {
|
|
9
|
+
baseDir;
|
|
10
|
+
fileMappings = new Map();
|
|
11
|
+
pathToGuid = new Map(); // Reverse index for O(1) path lookups
|
|
12
|
+
constructor(baseDir = config.syncDir) {
|
|
13
|
+
this.baseDir = path.resolve(baseDir);
|
|
14
|
+
this.ensureDirectory(this.baseDir);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Write all script nodes to the filesystem
|
|
18
|
+
*/
|
|
19
|
+
writeTree(nodes) {
|
|
20
|
+
log.info("Writing tree to filesystem...");
|
|
21
|
+
// Clear existing mappings
|
|
22
|
+
this.fileMappings.clear();
|
|
23
|
+
this.pathToGuid.clear();
|
|
24
|
+
// Collect all script nodes for batch writing
|
|
25
|
+
const scriptNodes = [];
|
|
26
|
+
for (const node of nodes.values()) {
|
|
27
|
+
if (this.isScriptNode(node)) {
|
|
28
|
+
scriptNodes.push(node);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
this.writeBatch(scriptNodes);
|
|
32
|
+
log.success(`Wrote ${this.fileMappings.size} scripts to filesystem`);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Write multiple scripts in a batch for improved I/O efficiency
|
|
36
|
+
*/
|
|
37
|
+
writeBatch(nodes) {
|
|
38
|
+
// Pre-compute all file paths and collect writes
|
|
39
|
+
const writes = [];
|
|
40
|
+
const dirsToCreate = new Set();
|
|
41
|
+
const batchPathToGuid = new Map();
|
|
42
|
+
for (const node of nodes) {
|
|
43
|
+
if (!this.isScriptNode(node) || node.source === undefined)
|
|
44
|
+
continue;
|
|
45
|
+
const filePath = this.getFilePathWithCollisionMap(node, batchPathToGuid);
|
|
46
|
+
const dirPath = path.dirname(filePath);
|
|
47
|
+
writes.push({ node, filePath, dirPath });
|
|
48
|
+
dirsToCreate.add(dirPath);
|
|
49
|
+
batchPathToGuid.set(path.resolve(filePath), node.guid);
|
|
50
|
+
}
|
|
51
|
+
// Batch create all directories first (sorted by depth to ensure parents exist)
|
|
52
|
+
const sortedDirs = Array.from(dirsToCreate).sort((a, b) => a.length - b.length);
|
|
53
|
+
for (const dir of sortedDirs) {
|
|
54
|
+
this.ensureDirectory(dir);
|
|
55
|
+
}
|
|
56
|
+
for (const { node, filePath } of writes) {
|
|
57
|
+
try {
|
|
58
|
+
fs.writeFileSync(filePath, node.source, "utf-8");
|
|
59
|
+
this.fileMappings.set(node.guid, {
|
|
60
|
+
guid: node.guid,
|
|
61
|
+
filePath: filePath,
|
|
62
|
+
className: node.className,
|
|
63
|
+
});
|
|
64
|
+
this.pathToGuid.set(path.resolve(filePath), node.guid);
|
|
65
|
+
log.script(this.getRelativePath(filePath), "updated");
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
log.error(`Failed to write script ${filePath}:`, error);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Write or update a single script
|
|
74
|
+
*/
|
|
75
|
+
writeScript(node) {
|
|
76
|
+
if (!this.isScriptNode(node)) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
// Allow empty-string sources on new scripts; only skip if source is truly undefined
|
|
80
|
+
if (node.source === undefined) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
const existingMapping = this.fileMappings.get(node.guid);
|
|
84
|
+
const filePath = this.getFilePath(node);
|
|
85
|
+
const dirPath = path.dirname(filePath);
|
|
86
|
+
const previousPath = existingMapping?.filePath;
|
|
87
|
+
const pathChanged = previousPath && previousPath !== filePath;
|
|
88
|
+
// Ensure directory exists
|
|
89
|
+
this.ensureDirectory(dirPath);
|
|
90
|
+
// Write file
|
|
91
|
+
try {
|
|
92
|
+
fs.writeFileSync(filePath, node.source, "utf-8");
|
|
93
|
+
// If the target path changed for this guid, remove the old file to avoid stale copies
|
|
94
|
+
if (pathChanged && previousPath && fs.existsSync(previousPath)) {
|
|
95
|
+
fs.unlinkSync(previousPath);
|
|
96
|
+
this.pathToGuid.delete(path.resolve(previousPath));
|
|
97
|
+
this.cleanupParentsIfEmpty(path.dirname(previousPath));
|
|
98
|
+
}
|
|
99
|
+
// Update mapping and reverse index
|
|
100
|
+
this.fileMappings.set(node.guid, {
|
|
101
|
+
guid: node.guid,
|
|
102
|
+
filePath: filePath,
|
|
103
|
+
className: node.className,
|
|
104
|
+
});
|
|
105
|
+
this.pathToGuid.set(path.resolve(filePath), node.guid);
|
|
106
|
+
log.script(this.getRelativePath(filePath), "updated");
|
|
107
|
+
return filePath;
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
log.error(`Failed to write script ${filePath}:`, error);
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Delete a script file
|
|
116
|
+
*/
|
|
117
|
+
deleteScript(guid) {
|
|
118
|
+
const mapping = this.fileMappings.get(guid);
|
|
119
|
+
if (!mapping) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
const deleted = this.deleteFilePathInternal(mapping.filePath);
|
|
124
|
+
this.fileMappings.delete(guid);
|
|
125
|
+
this.pathToGuid.delete(path.resolve(mapping.filePath));
|
|
126
|
+
return deleted;
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
log.error(`Failed to delete script ${mapping.filePath}:`, error);
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Delete a script file by path even if the mapping is missing
|
|
135
|
+
*/
|
|
136
|
+
deleteFilePath(filePath) {
|
|
137
|
+
try {
|
|
138
|
+
return this.deleteFilePathInternal(filePath);
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
log.error(`Failed to delete script ${filePath}:`, error);
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get the filesystem path for a node
|
|
147
|
+
*/
|
|
148
|
+
getFilePath(node) {
|
|
149
|
+
return this.getFilePathWithCollisionMap(node);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Get the filesystem path for a node, with optional collision map for batch operations
|
|
153
|
+
*/
|
|
154
|
+
getFilePathWithCollisionMap(node, batchCollisionMap) {
|
|
155
|
+
// Build the path from the node's hierarchy. For scripts, we only use the parent path
|
|
156
|
+
// as directories, then add the script file name. This prevents creating an extra
|
|
157
|
+
// folder named after the script itself.
|
|
158
|
+
const parts = [];
|
|
159
|
+
const dirSegments = this.isScriptNode(node)
|
|
160
|
+
? node.path.slice(0, Math.max(0, node.path.length - 1))
|
|
161
|
+
: node.path;
|
|
162
|
+
for (const segment of dirSegments) {
|
|
163
|
+
parts.push(this.sanitizeName(segment));
|
|
164
|
+
}
|
|
165
|
+
// If this is a script, add the script name as a file
|
|
166
|
+
if (this.isScriptNode(node)) {
|
|
167
|
+
const scriptName = this.getScriptFileName(node);
|
|
168
|
+
parts.push(scriptName);
|
|
169
|
+
}
|
|
170
|
+
const desiredPath = path.join(this.baseDir, ...parts);
|
|
171
|
+
const normalizedDesiredPath = path.resolve(desiredPath);
|
|
172
|
+
// Check for collisions in both the persistent mappings and the batch collision map
|
|
173
|
+
const existingGuid = this.findGuidByFilePath(desiredPath);
|
|
174
|
+
const batchGuid = batchCollisionMap?.get(normalizedDesiredPath);
|
|
175
|
+
const collision = existingGuid || batchGuid;
|
|
176
|
+
// If another GUID already owns this path, disambiguate using a stable suffix
|
|
177
|
+
if (collision && collision !== node.guid) {
|
|
178
|
+
const ext = config.scriptExtension;
|
|
179
|
+
const uniqueName = `${this.sanitizeName(node.name)}__${node.guid.slice(0, 8)}${ext}`;
|
|
180
|
+
const uniqueParts = [...parts.slice(0, -1), uniqueName];
|
|
181
|
+
return path.join(this.baseDir, ...uniqueParts);
|
|
182
|
+
}
|
|
183
|
+
return desiredPath;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Get the appropriate filename for a script node
|
|
187
|
+
*/
|
|
188
|
+
getScriptFileName(node) {
|
|
189
|
+
const ext = config.scriptExtension;
|
|
190
|
+
// If the script has the same name as its parent, use init pattern
|
|
191
|
+
// const parentName = node.path[node.path.length - 2]; // 2 to get parent
|
|
192
|
+
// if (node.name === parentName) {
|
|
193
|
+
// log.info(
|
|
194
|
+
// `Using init file pattern for script ${node.name} because it matches its parent directory name (${parentName}).`
|
|
195
|
+
// );
|
|
196
|
+
// return `init${ext}`;
|
|
197
|
+
// }
|
|
198
|
+
let name = this.sanitizeName(node.name);
|
|
199
|
+
if (node.className === "Script") {
|
|
200
|
+
name = `${name}.server`;
|
|
201
|
+
}
|
|
202
|
+
else if (node.className === "LocalScript") {
|
|
203
|
+
name = `${name}.client`;
|
|
204
|
+
}
|
|
205
|
+
else if (node.className === "ModuleScript") {
|
|
206
|
+
if (config.suffixModuleScripts) {
|
|
207
|
+
name = `${name}.module`;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return `${name}${ext}`;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Sanitize a name for use in filesystem
|
|
214
|
+
*/
|
|
215
|
+
sanitizeName(name) {
|
|
216
|
+
// Replace invalid filesystem characters
|
|
217
|
+
return name.replace(/[<>:"|?*]/g, "_");
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Check if a node is a script
|
|
221
|
+
*/
|
|
222
|
+
isScriptNode(node) {
|
|
223
|
+
return (node.className === "Script" ||
|
|
224
|
+
node.className === "LocalScript" ||
|
|
225
|
+
node.className === "ModuleScript");
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Ensure a directory exists
|
|
229
|
+
*/
|
|
230
|
+
ensureDirectory(dirPath) {
|
|
231
|
+
if (!fs.existsSync(dirPath)) {
|
|
232
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Internal helper to remove a file and clean mapping
|
|
237
|
+
*/
|
|
238
|
+
deleteFilePathInternal(filePath) {
|
|
239
|
+
const normalized = path.resolve(filePath);
|
|
240
|
+
if (fs.existsSync(normalized)) {
|
|
241
|
+
fs.unlinkSync(normalized);
|
|
242
|
+
log.script(this.getRelativePath(normalized), "deleted");
|
|
243
|
+
}
|
|
244
|
+
const guid = this.pathToGuid.get(normalized);
|
|
245
|
+
if (guid) {
|
|
246
|
+
this.fileMappings.delete(guid);
|
|
247
|
+
this.pathToGuid.delete(normalized);
|
|
248
|
+
}
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Find the GUID that currently owns a file path, if any
|
|
253
|
+
*/
|
|
254
|
+
findGuidByFilePath(filePath) {
|
|
255
|
+
const normalized = path.resolve(filePath);
|
|
256
|
+
for (const [guid, mapping] of this.fileMappings) {
|
|
257
|
+
if (path.resolve(mapping.filePath) === normalized) {
|
|
258
|
+
return guid;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return undefined;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Get path relative to base directory
|
|
265
|
+
*/
|
|
266
|
+
getRelativePath(filePath) {
|
|
267
|
+
return path.relative(this.baseDir, filePath);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Get file mapping by GUID
|
|
271
|
+
*/
|
|
272
|
+
getMapping(guid) {
|
|
273
|
+
return this.fileMappings.get(guid);
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Get GUID by file path
|
|
277
|
+
*/
|
|
278
|
+
getGuidByPath(filePath) {
|
|
279
|
+
return this.pathToGuid.get(path.resolve(filePath));
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Get all file mappings
|
|
283
|
+
*/
|
|
284
|
+
getAllMappings() {
|
|
285
|
+
return this.fileMappings;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Get the base directory
|
|
289
|
+
*/
|
|
290
|
+
getBaseDir() {
|
|
291
|
+
return this.baseDir;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Clean up empty directories
|
|
295
|
+
*/
|
|
296
|
+
cleanupEmptyDirectories() {
|
|
297
|
+
this.cleanupEmptyDirsRecursive(this.baseDir);
|
|
298
|
+
}
|
|
299
|
+
cleanupEmptyDirsRecursive(dirPath) {
|
|
300
|
+
if (!fs.existsSync(dirPath)) {
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
304
|
+
// Recursively check subdirectories
|
|
305
|
+
for (const entry of entries) {
|
|
306
|
+
if (entry.isDirectory()) {
|
|
307
|
+
const subPath = path.join(dirPath, entry.name);
|
|
308
|
+
this.cleanupEmptyDirsRecursive(subPath);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
// Check if directory is now empty
|
|
312
|
+
const updatedEntries = fs.readdirSync(dirPath);
|
|
313
|
+
if (updatedEntries.length === 0 && dirPath !== this.baseDir) {
|
|
314
|
+
fs.rmdirSync(dirPath);
|
|
315
|
+
return true;
|
|
316
|
+
}
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Walk up from a directory and remove empty parents until baseDir is reached.
|
|
321
|
+
*/
|
|
322
|
+
cleanupParentsIfEmpty(startDir) {
|
|
323
|
+
let current = path.resolve(startDir);
|
|
324
|
+
const root = this.baseDir;
|
|
325
|
+
while (current.startsWith(root)) {
|
|
326
|
+
if (current === root) {
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
const entries = fs.existsSync(current)
|
|
330
|
+
? fs.readdirSync(current, { withFileTypes: true })
|
|
331
|
+
: [];
|
|
332
|
+
if (entries.length === 0) {
|
|
333
|
+
fs.rmdirSync(current);
|
|
334
|
+
current = path.dirname(current);
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
//# sourceMappingURL=fileWriter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileWriter.js","sourceRoot":"","sources":["../../src/fs/fileWriter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { InstanceData } from "../ipc/messages.js";
|
|
2
|
+
/**
|
|
3
|
+
* Represents a node in the virtual DataModel tree
|
|
4
|
+
*/
|
|
5
|
+
export interface TreeNode {
|
|
6
|
+
guid: string;
|
|
7
|
+
className: string;
|
|
8
|
+
name: string;
|
|
9
|
+
path: string[];
|
|
10
|
+
parentGuid?: string | null;
|
|
11
|
+
source?: string;
|
|
12
|
+
children: Map<string, TreeNode>;
|
|
13
|
+
parent?: TreeNode;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Manages the in-memory representation of Studio's DataModel
|
|
17
|
+
*/
|
|
18
|
+
export declare class TreeManager {
|
|
19
|
+
private nodes;
|
|
20
|
+
private pathIndex;
|
|
21
|
+
private root;
|
|
22
|
+
private pathKey;
|
|
23
|
+
private addToPathIndex;
|
|
24
|
+
private removeFromPathIndex;
|
|
25
|
+
private registerSubtree;
|
|
26
|
+
private unregisterSubtree;
|
|
27
|
+
updateInstance(instance: InstanceData): {
|
|
28
|
+
node: TreeNode;
|
|
29
|
+
pathChanged: boolean;
|
|
30
|
+
nameChanged: boolean;
|
|
31
|
+
parentChanged: boolean;
|
|
32
|
+
isNew: boolean;
|
|
33
|
+
prevPath?: string[];
|
|
34
|
+
prevName?: string;
|
|
35
|
+
} | null;
|
|
36
|
+
/**
|
|
37
|
+
* Process a full snapshot from Studio
|
|
38
|
+
*/
|
|
39
|
+
applyFullSnapshot(instances: InstanceData[]): void;
|
|
40
|
+
/**
|
|
41
|
+
* Update child paths iteratively
|
|
42
|
+
*/
|
|
43
|
+
private recalculateChildPaths;
|
|
44
|
+
getDescendantScripts(guid: string): TreeNode[];
|
|
45
|
+
private isScriptNode;
|
|
46
|
+
private pathsEqual;
|
|
47
|
+
/**
|
|
48
|
+
* Delete an instance by GUID
|
|
49
|
+
*/
|
|
50
|
+
deleteInstance(guid: string): TreeNode | null;
|
|
51
|
+
/**
|
|
52
|
+
* Update script source only
|
|
53
|
+
*/
|
|
54
|
+
updateScriptSource(guid: string, source: string): void;
|
|
55
|
+
/**
|
|
56
|
+
* Get a node by GUID
|
|
57
|
+
*/
|
|
58
|
+
getNode(guid: string): TreeNode | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Get all nodes
|
|
61
|
+
*/
|
|
62
|
+
getAllNodes(): Map<string, TreeNode>;
|
|
63
|
+
/**
|
|
64
|
+
* Get all script nodes
|
|
65
|
+
*/
|
|
66
|
+
getScriptNodes(): TreeNode[];
|
|
67
|
+
/**
|
|
68
|
+
* Find a node by its path
|
|
69
|
+
*/
|
|
70
|
+
private findNodeByPath;
|
|
71
|
+
/**
|
|
72
|
+
* Re-parent a node based on its path
|
|
73
|
+
*/
|
|
74
|
+
private reparentNode;
|
|
75
|
+
/**
|
|
76
|
+
* Get tree statistics
|
|
77
|
+
*/
|
|
78
|
+
getStats(): {
|
|
79
|
+
totalNodes: number;
|
|
80
|
+
scriptNodes: number;
|
|
81
|
+
maxDepth: number;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=treeManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"treeManager.d.ts","sourceRoot":"","sources":["../../src/fs/treeManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,QAAQ,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,IAAI,CAAyB;IAErC,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,iBAAiB;IAalB,cAAc,CAAC,QAAQ,EAAE,YAAY,GAAG;QAC7C,IAAI,EAAE,QAAQ,CAAC;QACf,WAAW,EAAE,OAAO,CAAC;QACrB,WAAW,EAAE,OAAO,CAAC;QACrB,aAAa,EAAE,OAAO,CAAC;QACvB,KAAK,EAAE,OAAO,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI;IA4ER;;OAEG;IACI,iBAAiB,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,IAAI;IA2EzD;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAatB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE;IAwBrD,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,UAAU;IAKlB;;OAEG;IACI,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAgCpD;;OAEG;IACI,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAU7D;;OAEG;IACI,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAIlD;;OAEG;IACI,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC;IAI3C;;OAEG;IACI,cAAc,IAAI,QAAQ,EAAE;IAMnC;;OAEG;IACH,OAAO,CAAC,cAAc;IAiBtB;;OAEG;IACH,OAAO,CAAC,YAAY;IAgDpB;;OAEG;IACI,QAAQ,IAAI;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB;CAoBF"}
|