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,112 @@
1
+ /**
2
+ * Types for communication protocol between Studio and Daemon
3
+ */
4
+ export type InstanceClassName = "Script" | "LocalScript" | "ModuleScript" | "Folder" | "Model" | "Part" | "MeshPart" | "Tool" | "Configuration" | string;
5
+ /**
6
+ * Represents a single instance in the DataModel
7
+ */
8
+ export interface InstanceData {
9
+ guid: string;
10
+ className: InstanceClassName;
11
+ name: string;
12
+ path: string[];
13
+ parentGuid?: string | null;
14
+ source?: string;
15
+ properties?: Record<string, unknown>;
16
+ attributes?: Record<string, unknown>;
17
+ }
18
+ export interface SnapshotRequestOptions {
19
+ includeProperties?: boolean;
20
+ scriptsAndDescendantsOnly?: boolean;
21
+ }
22
+ /**
23
+ * Messages from Studio → Daemon
24
+ */
25
+ export type StudioPayloadMessage = FullSnapshotMessage | InstanceUpdatedMessage | ScriptChangedMessage | DeletedMessage | PingMessage | ClientDisconnect | PushConfigMessage;
26
+ export interface BatchMessage {
27
+ type: "batch";
28
+ messages: StudioPayloadMessage[];
29
+ }
30
+ export type StudioMessage = StudioPayloadMessage | BatchMessage;
31
+ export interface FullSnapshotMessage {
32
+ type: "fullSnapshot";
33
+ data: InstanceData[];
34
+ }
35
+ export interface InstanceUpdatedMessage {
36
+ type: "instanceUpdated";
37
+ data: InstanceData;
38
+ }
39
+ export interface ScriptChangedMessage {
40
+ type: "scriptChanged";
41
+ data: {
42
+ guid: string;
43
+ path: string[];
44
+ className: InstanceClassName;
45
+ source: string;
46
+ };
47
+ }
48
+ export interface DeletedMessage {
49
+ type: "deleted";
50
+ data: {
51
+ guid: string;
52
+ };
53
+ }
54
+ export interface PingMessage {
55
+ type: "ping";
56
+ }
57
+ export interface ClientDisconnect {
58
+ type: "clientDisconnect";
59
+ }
60
+ export interface PushConfigMessage {
61
+ type: "pushConfig";
62
+ config: PushConfig;
63
+ }
64
+ /**
65
+ * Messages from Daemon → Studio
66
+ */
67
+ export type DaemonMessage = PatchScriptMessage | RequestSnapshotMessage | PongMessage | ErrorMessage | BuildSnapshotMessage | RequestPushConfigMessage | PushSnapshotMessage;
68
+ export interface PatchScriptMessage {
69
+ type: "patchScript";
70
+ guid: string;
71
+ source: string;
72
+ }
73
+ export interface RequestSnapshotMessage {
74
+ type: "requestSnapshot";
75
+ options?: SnapshotRequestOptions;
76
+ }
77
+ export interface PongMessage {
78
+ type: "pong";
79
+ }
80
+ export interface ErrorMessage {
81
+ type: "error";
82
+ message: string;
83
+ }
84
+ export interface BuildSnapshotMessage {
85
+ type: "buildSnapshot";
86
+ data: InstanceData[];
87
+ }
88
+ export interface RequestPushConfigMessage {
89
+ type: "requestPushConfig";
90
+ }
91
+ export interface PushSnapshotMessage {
92
+ type: "pushSnapshot";
93
+ mappings: PushSnapshotMapping[];
94
+ }
95
+ export interface PushSnapshotMapping {
96
+ destination: string[];
97
+ destructive?: boolean;
98
+ instances: InstanceData[];
99
+ }
100
+ export interface PushConfig {
101
+ mappings: PushConfigMapping[];
102
+ port?: number;
103
+ debugMode?: boolean;
104
+ deleteOrphansOnConnect?: boolean;
105
+ }
106
+ export interface PushConfigMapping {
107
+ source: string;
108
+ destination: string[];
109
+ destructive?: boolean;
110
+ rojoMode?: boolean;
111
+ }
112
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/ipc/messages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Types for communication protocol between Studio and Daemon
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/ipc/messages.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,50 @@
1
+ import type { StudioMessage, DaemonMessage } from "./messages.js";
2
+ import type { SnapshotRequestOptions } from "./messages.js";
3
+ import type { Server as HttpServer } from "http";
4
+ export type MessageHandler = (message: StudioMessage) => void;
5
+ interface IPCServerOptions {
6
+ requestSnapshotOnConnect?: boolean;
7
+ }
8
+ export declare class IPCServer {
9
+ private wss;
10
+ private client;
11
+ private messageHandler;
12
+ private connectionHandler;
13
+ private requestSnapshotOnConnect;
14
+ constructor(port?: number, server?: HttpServer, options?: IPCServerOptions);
15
+ private setupServer;
16
+ /**
17
+ * Register a handler for incoming Studio messages
18
+ */
19
+ onMessage(handler: MessageHandler): void;
20
+ /**
21
+ * Register a handler that fires when a Studio client connects
22
+ */
23
+ onConnection(handler: () => void): void;
24
+ /**
25
+ * Send a message to the connected Studio client
26
+ */
27
+ send(message: DaemonMessage): boolean;
28
+ /**
29
+ * Send a patch to update a script's source in Studio
30
+ */
31
+ patchScript(guid: string, source: string): boolean;
32
+ /**
33
+ * Send an error message to Studio
34
+ */
35
+ sendError(message: string): boolean;
36
+ /**
37
+ * Request a full snapshot from Studio
38
+ */
39
+ requestSnapshot(options?: SnapshotRequestOptions): boolean;
40
+ /**
41
+ * Check if a client is connected
42
+ */
43
+ isConnected(): boolean;
44
+ /**
45
+ * Close the server
46
+ */
47
+ close(): void;
48
+ }
49
+ export {};
50
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/ipc/server.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC;AAEjD,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;AAE9D,UAAU,gBAAgB;IACxB,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,wBAAwB,CAAU;gBAE9B,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,gBAAgB;IAoB1E,OAAO,CAAC,WAAW;IAyEnB;;OAEG;IACI,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAI/C;;OAEG;IACI,YAAY,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAI9C;;OAEG;IACI,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO;IAgB5C;;OAEG;IACI,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAQzD;;OAEG;IACI,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAO1C;;OAEG;IACI,eAAe,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,OAAO;IAOjE;;OAEG;IACI,WAAW,IAAI,OAAO;IAI7B;;OAEG;IACI,KAAK,IAAI,IAAI;CASrB"}
@@ -0,0 +1,168 @@
1
+ import { WebSocketServer, WebSocket } from "ws";
2
+ import { log } from "../util/log.js";
3
+ export class IPCServer {
4
+ wss;
5
+ client = null;
6
+ messageHandler = null;
7
+ connectionHandler = null;
8
+ requestSnapshotOnConnect;
9
+ constructor(port, server, options) {
10
+ this.requestSnapshotOnConnect = options?.requestSnapshotOnConnect !== false;
11
+ if (server) {
12
+ // Use existing HTTP server
13
+ this.wss = new WebSocketServer({
14
+ server,
15
+ // perMessageDeflate: false, // Roblox WebSocket client does not negotiate RSV2/RSV3 extensions
16
+ maxPayload: 256 * 1024 * 1024, // 256 MB
17
+ });
18
+ }
19
+ else {
20
+ // Create standalone WebSocket server
21
+ this.wss = new WebSocketServer({
22
+ port: port || 8080,
23
+ // perMessageDeflate: false, // avoid RSV2/RSV3 bits from compression
24
+ maxPayload: 256 * 1024 * 1024, // 256 MB
25
+ });
26
+ }
27
+ this.setupServer();
28
+ }
29
+ setupServer() {
30
+ this.wss.on("connection", (ws) => {
31
+ log.info("Studio client connected");
32
+ log.info("Waiting for Studio messages...");
33
+ // Disconnect previous client if exists
34
+ if (this.client) {
35
+ log.warn("Disconnecting previous client");
36
+ this.client.close();
37
+ }
38
+ this.client = ws;
39
+ if (this.connectionHandler) {
40
+ this.connectionHandler();
41
+ }
42
+ ws.on("message", (data) => {
43
+ try {
44
+ const message = JSON.parse(data.toString());
45
+ log.debug(`Received: ${message.type}`);
46
+ if (this.messageHandler) {
47
+ this.messageHandler(message);
48
+ }
49
+ }
50
+ catch (error) {
51
+ log.error("Failed to parse message:", error);
52
+ this.sendError("Invalid JSON message");
53
+ }
54
+ });
55
+ ws.on("close", () => {
56
+ log.info("Studio client disconnected");
57
+ this.client = null;
58
+ });
59
+ ws.on("error", (error) => {
60
+ log.error("WebSocket error:", error);
61
+ });
62
+ // Set up ping/pong to keep connection alive
63
+ ws.on("pong", () => {
64
+ log.debug("Received pong from client");
65
+ });
66
+ // Send ping every 30 seconds
67
+ const pingInterval = setInterval(() => {
68
+ if (this.client === ws && ws.readyState === WebSocket.OPEN) {
69
+ ws.ping();
70
+ }
71
+ else {
72
+ clearInterval(pingInterval);
73
+ }
74
+ }, 30000);
75
+ // Request initial snapshot after a brief delay
76
+ if (this.requestSnapshotOnConnect) {
77
+ setTimeout(() => {
78
+ if (this.client === ws) {
79
+ this.send({ type: "requestSnapshot" });
80
+ }
81
+ }, 100);
82
+ }
83
+ });
84
+ this.wss.on("listening", () => {
85
+ log.success("WebSocket server ready");
86
+ });
87
+ this.wss.on("error", (error) => {
88
+ log.error("WebSocket server error:", error);
89
+ });
90
+ }
91
+ /**
92
+ * Register a handler for incoming Studio messages
93
+ */
94
+ onMessage(handler) {
95
+ this.messageHandler = handler;
96
+ }
97
+ /**
98
+ * Register a handler that fires when a Studio client connects
99
+ */
100
+ onConnection(handler) {
101
+ this.connectionHandler = handler;
102
+ }
103
+ /**
104
+ * Send a message to the connected Studio client
105
+ */
106
+ send(message) {
107
+ if (!this.client || this.client.readyState !== WebSocket.OPEN) {
108
+ log.warn("Cannot send message: no connected client");
109
+ return false;
110
+ }
111
+ try {
112
+ this.client.send(JSON.stringify(message));
113
+ log.debug(`Sent: ${message.type}`);
114
+ return true;
115
+ }
116
+ catch (error) {
117
+ log.error("Failed to send message:", error);
118
+ return false;
119
+ }
120
+ }
121
+ /**
122
+ * Send a patch to update a script's source in Studio
123
+ */
124
+ patchScript(guid, source) {
125
+ return this.send({
126
+ type: "patchScript",
127
+ guid,
128
+ source,
129
+ });
130
+ }
131
+ /**
132
+ * Send an error message to Studio
133
+ */
134
+ sendError(message) {
135
+ return this.send({
136
+ type: "error",
137
+ message,
138
+ });
139
+ }
140
+ /**
141
+ * Request a full snapshot from Studio
142
+ */
143
+ requestSnapshot(options) {
144
+ return this.send({
145
+ type: "requestSnapshot",
146
+ options,
147
+ });
148
+ }
149
+ /**
150
+ * Check if a client is connected
151
+ */
152
+ isConnected() {
153
+ return this.client !== null && this.client.readyState === WebSocket.OPEN;
154
+ }
155
+ /**
156
+ * Close the server
157
+ */
158
+ close() {
159
+ if (this.client) {
160
+ this.client.close();
161
+ }
162
+ this.wss.close();
163
+ log.info("WebSocket server closed.");
164
+ log.info("Exiting...");
165
+ process.exit(0);
166
+ }
167
+ }
168
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/ipc/server.ts"],"names":[],"mappings":"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"}
package/dist/pack.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ interface PackOptions {
2
+ outputPath?: string;
3
+ scriptsAndDescendantsOnly?: boolean;
4
+ }
5
+ export declare class PackCommand {
6
+ private ipc;
7
+ private outputPath;
8
+ private scriptsAndDescendantsOnly;
9
+ constructor(options?: PackOptions);
10
+ run(): Promise<void>;
11
+ private requestSnapshot;
12
+ private readExistingSourcemap;
13
+ private regenerateSourcemap;
14
+ private packIntoSourcemap;
15
+ private writeSourcemap;
16
+ private pathClassKey;
17
+ }
18
+ export {};
19
+ //# sourceMappingURL=pack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../src/pack.ts"],"names":[],"mappings":"AAWA,UAAU,WAAW;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC;AAuBD,qBAAa,WAAW;IACtB,OAAO,CAAC,GAAG,CAAY;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,yBAAyB,CAAU;gBAE/B,OAAO,GAAE,WAAgB;IAQxB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAoBnB,eAAe;IAwC7B,OAAO,CAAC,qBAAqB;IAgB7B,OAAO,CAAC,mBAAmB;IAuF3B,OAAO,CAAC,iBAAiB;IA+EzB,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,YAAY;CAGrB"}
package/dist/pack.js ADDED
@@ -0,0 +1,225 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { IPCServer } from "./ipc/server.js";
4
+ import { config } from "./config.js";
5
+ import { log } from "./util/log.js";
6
+ export class PackCommand {
7
+ ipc;
8
+ outputPath;
9
+ scriptsAndDescendantsOnly;
10
+ constructor(options = {}) {
11
+ this.outputPath = path.resolve(options.outputPath ?? config.sourcemapPath);
12
+ this.scriptsAndDescendantsOnly = Boolean(options.scriptsAndDescendantsOnly);
13
+ this.ipc = new IPCServer(config.port, undefined, {
14
+ requestSnapshotOnConnect: false,
15
+ });
16
+ }
17
+ async run() {
18
+ log.info(`Waiting for Studio to connect on port ${config.port}...`);
19
+ const snapshot = await this.requestSnapshot({
20
+ includeProperties: true,
21
+ scriptsAndDescendantsOnly: this.scriptsAndDescendantsOnly,
22
+ });
23
+ if (!snapshot) {
24
+ log.error("Failed to receive snapshot from Studio for packing.");
25
+ return;
26
+ }
27
+ const existing = this.readExistingSourcemap();
28
+ const regenerated = this.regenerateSourcemap(snapshot, existing);
29
+ const packedCount = this.packIntoSourcemap(snapshot, regenerated);
30
+ this.writeSourcemap(regenerated, this.outputPath);
31
+ log.success(`Packed ${packedCount} node(s) into ${this.outputPath}`);
32
+ }
33
+ async requestSnapshot(options) {
34
+ return new Promise((resolve) => {
35
+ let timeoutHandle = null;
36
+ let resolved = false;
37
+ const finalize = (result) => {
38
+ if (resolved)
39
+ return;
40
+ resolved = true;
41
+ if (timeoutHandle) {
42
+ clearTimeout(timeoutHandle);
43
+ timeoutHandle = null;
44
+ }
45
+ setTimeout(() => {
46
+ this.ipc.close();
47
+ }, 200);
48
+ resolve(result);
49
+ };
50
+ this.ipc.onMessage((message) => {
51
+ if (message.type !== "fullSnapshot")
52
+ return;
53
+ finalize(message.data);
54
+ });
55
+ this.ipc.onConnection(() => {
56
+ log.info("Studio connected. Requesting snapshot...");
57
+ this.ipc.requestSnapshot(options);
58
+ });
59
+ timeoutHandle = setTimeout(() => {
60
+ log.error("Timed out waiting for Studio snapshot.");
61
+ finalize(null);
62
+ }, 30000);
63
+ });
64
+ }
65
+ readExistingSourcemap() {
66
+ if (!fs.existsSync(this.outputPath)) {
67
+ return null;
68
+ }
69
+ try {
70
+ const raw = fs.readFileSync(this.outputPath, "utf8");
71
+ return JSON.parse(raw);
72
+ }
73
+ catch (error) {
74
+ log.warn(`Failed to read existing sourcemap at ${this.outputPath}: ${error}`);
75
+ return null;
76
+ }
77
+ }
78
+ regenerateSourcemap(snapshot, existing) {
79
+ const root = {
80
+ name: "Game",
81
+ className: "DataModel",
82
+ children: [],
83
+ };
84
+ const guidFilePaths = new Map();
85
+ const pathClassFilePaths = new Map();
86
+ const pathClassCursor = new Map();
87
+ const indexExisting = (node, currentPath) => {
88
+ const nodePath = [...currentPath, node.name];
89
+ if (node.filePaths && node.filePaths.length > 0) {
90
+ if (node.guid) {
91
+ guidFilePaths.set(node.guid, node.filePaths);
92
+ }
93
+ const key = this.pathClassKey(nodePath, node.className);
94
+ const bucket = pathClassFilePaths.get(key) ?? [];
95
+ bucket.push(node.filePaths);
96
+ pathClassFilePaths.set(key, bucket);
97
+ }
98
+ for (const child of node.children ?? []) {
99
+ indexExisting(child, nodePath);
100
+ }
101
+ };
102
+ for (const child of existing?.children ?? []) {
103
+ indexExisting(child, []);
104
+ }
105
+ const byGuid = new Map();
106
+ byGuid.set("root", root);
107
+ const sorted = [...snapshot].sort((a, b) => {
108
+ if (a.path.length !== b.path.length) {
109
+ return a.path.length - b.path.length;
110
+ }
111
+ return a.path.join("/").localeCompare(b.path.join("/"));
112
+ });
113
+ for (const item of sorted) {
114
+ const node = {
115
+ name: item.name,
116
+ className: item.className,
117
+ guid: item.guid,
118
+ };
119
+ const directFilePaths = guidFilePaths.get(item.guid);
120
+ if (directFilePaths && directFilePaths.length > 0) {
121
+ node.filePaths = directFilePaths;
122
+ }
123
+ else {
124
+ const key = this.pathClassKey(item.path, item.className);
125
+ const bucket = pathClassFilePaths.get(key);
126
+ if (bucket && bucket.length > 0) {
127
+ const cursor = pathClassCursor.get(key) ?? 0;
128
+ const candidate = bucket[cursor];
129
+ if (candidate && candidate.length > 0) {
130
+ node.filePaths = candidate;
131
+ pathClassCursor.set(key, cursor + 1);
132
+ }
133
+ }
134
+ }
135
+ let parentNode = root;
136
+ if (item.parentGuid && item.parentGuid !== "root") {
137
+ parentNode = byGuid.get(item.parentGuid) ?? root;
138
+ }
139
+ if (!parentNode.children) {
140
+ parentNode.children = [];
141
+ }
142
+ parentNode.children.push(node);
143
+ byGuid.set(item.guid, node);
144
+ }
145
+ return root;
146
+ }
147
+ packIntoSourcemap(snapshot, sourcemap) {
148
+ const byGuid = new Map();
149
+ const byPathClass = new Map();
150
+ for (const item of snapshot) {
151
+ byGuid.set(item.guid, item);
152
+ const key = this.pathClassKey(item.path, item.className);
153
+ const bucket = byPathClass.get(key) ?? [];
154
+ bucket.push(item);
155
+ byPathClass.set(key, bucket);
156
+ }
157
+ const usedGuids = new Set();
158
+ let packed = 0;
159
+ const visit = (node, currentPath) => {
160
+ const nodePath = [...currentPath, node.name];
161
+ let match;
162
+ if (node.guid) {
163
+ const direct = byGuid.get(node.guid);
164
+ if (direct) {
165
+ match = direct;
166
+ usedGuids.add(direct.guid);
167
+ }
168
+ }
169
+ if (!match) {
170
+ const key = this.pathClassKey(nodePath, node.className);
171
+ const bucket = byPathClass.get(key);
172
+ if (bucket && bucket.length > 0) {
173
+ match = bucket.find((candidate) => !usedGuids.has(candidate.guid));
174
+ if (match) {
175
+ usedGuids.add(match.guid);
176
+ }
177
+ }
178
+ }
179
+ if (match) {
180
+ if (match.properties && Object.keys(match.properties).length > 0) {
181
+ node.properties = match.properties;
182
+ }
183
+ else if (!this.scriptsAndDescendantsOnly) {
184
+ delete node.properties;
185
+ }
186
+ if (match.attributes && Object.keys(match.attributes).length > 0) {
187
+ node.attributes = match.attributes;
188
+ }
189
+ else if (!this.scriptsAndDescendantsOnly) {
190
+ delete node.attributes;
191
+ }
192
+ if (match.properties || match.attributes) {
193
+ packed += 1;
194
+ }
195
+ }
196
+ else if (!this.scriptsAndDescendantsOnly) {
197
+ delete node.properties;
198
+ delete node.attributes;
199
+ }
200
+ for (const child of node.children ?? []) {
201
+ visit(child, nodePath);
202
+ }
203
+ };
204
+ for (const child of sourcemap.children ?? []) {
205
+ visit(child, []);
206
+ }
207
+ sourcemap._azul = {
208
+ packVersion: 1,
209
+ packedAt: new Date().toISOString(),
210
+ mode: this.scriptsAndDescendantsOnly ? "scripts-and-descendants" : "all",
211
+ };
212
+ return packed;
213
+ }
214
+ writeSourcemap(sourcemap, outputPath) {
215
+ const dir = path.dirname(outputPath);
216
+ if (dir && dir !== "." && !fs.existsSync(dir)) {
217
+ fs.mkdirSync(dir, { recursive: true });
218
+ }
219
+ fs.writeFileSync(outputPath, `${JSON.stringify(sourcemap, null, 2)}\n`, "utf8");
220
+ }
221
+ pathClassKey(pathSegments, className) {
222
+ return `${pathSegments.join("\u0001")}::${className}`;
223
+ }
224
+ }
225
+ //# sourceMappingURL=pack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack.js","sourceRoot":"","sources":["../src/pack.ts"],"names":[],"mappings":"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"}
package/dist/push.d.ts ADDED
@@ -0,0 +1,43 @@
1
+ interface PushOptions {
2
+ source?: string;
3
+ destination?: string;
4
+ destructive?: boolean;
5
+ usePlaceConfig?: boolean;
6
+ rojoMode?: boolean;
7
+ rojoProjectFile?: string;
8
+ applySourcemap?: boolean;
9
+ fromSourcemap?: boolean;
10
+ sourcemapPath?: string;
11
+ }
12
+ export declare class PushCommand {
13
+ private ipc;
14
+ private options;
15
+ private sourcemapPath;
16
+ private sourcemapIndex;
17
+ constructor(options?: PushOptions);
18
+ run(): Promise<void>;
19
+ private buildRojoInstances;
20
+ private collectMappings;
21
+ private parseDestination;
22
+ private buildPushInstancesFromSourcemap;
23
+ private inferSourcePrefixFromPath;
24
+ private pathStartsWith;
25
+ private resolveRojoProjectFiles;
26
+ /**
27
+ * Breadth-first search for all default.project.json under a root.
28
+ * Skips common vendor/ignored folders.
29
+ */
30
+ private findProjectJsons;
31
+ private collectLooseScripts;
32
+ private ensureFolder;
33
+ private isScriptFile;
34
+ private classifyScript;
35
+ /**
36
+ * Normalize source path strings from config, preferring the raw value but
37
+ * attempting obvious fixes (e.g., accidental leading '.' before a folder).
38
+ */
39
+ private expandSourceCandidates;
40
+ private waitForPushConfig;
41
+ }
42
+ export {};
43
+ //# sourceMappingURL=push.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../src/push.ts"],"names":[],"mappings":"AAuBA,UAAU,WAAW;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,GAAG,CAAY;IACvB,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,cAAc,CAAgD;gBAE1D,OAAO,GAAE,WAAgB;IAWxB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAyKnB,kBAAkB;YA8ElB,eAAe;IAkD7B,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,+BAA+B;IA6BvC,OAAO,CAAC,yBAAyB;IA6BjC,OAAO,CAAC,cAAc;YAUR,uBAAuB;IAuDrC;;;OAGG;YACW,gBAAgB;YAsChB,mBAAmB;IA+FjC,OAAO,CAAC,YAAY;IAkBpB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,cAAc;IAyBtB;;;OAGG;IACH,OAAO,CAAC,sBAAsB;YA2BhB,iBAAiB;CA+BhC"}