@hmcs/sdk 1.0.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/dist/host.cjs ADDED
@@ -0,0 +1,297 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Host API namespace for low-level HTTP communication with the Desktop Homunculus server.
5
+ *
6
+ * This module provides the foundational HTTP client functionality used internally
7
+ * by all other SDK modules. It handles the base URL configuration, URL construction,
8
+ * and HTTP methods with automatic error handling.
9
+ *
10
+ * **Note:** This module is primarily for internal SDK use. Most developers should
11
+ * use the higher-level namespaces like `vrm`, `signals`, etc.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * // Internal SDK usage (you typically won't need this directly)
16
+ * const response = await host.get(host.createUrl("vrm"));
17
+ * const vrms = await response.json();
18
+ *
19
+ * // URL construction with parameters
20
+ * const url = host.createUrl("vrm", { name: "MyCharacter" });
21
+ * // Results in: http://localhost:3100/vrm?name=MyCharacter
22
+ *
23
+ * // Configure the base URL (e.g., from an MCP server)
24
+ * host.configure({ baseUrl: "http://localhost:4000" });
25
+ * ```
26
+ */
27
+ /** Error thrown when the Homunculus HTTP API returns a non-OK response. */
28
+ class HomunculusApiError extends Error {
29
+ /** HTTP status code (e.g. 404, 500) */
30
+ statusCode;
31
+ /** The request endpoint URL */
32
+ endpoint;
33
+ /** The response body text */
34
+ body;
35
+ constructor(statusCode, endpoint, body) {
36
+ super(`${endpoint}: ${statusCode} ${body}`);
37
+ this.name = "HomunculusApiError";
38
+ this.statusCode = statusCode;
39
+ this.endpoint = endpoint;
40
+ this.body = body;
41
+ }
42
+ }
43
+ /** Error thrown when an NDJSON stream contains malformed data. */
44
+ class HomunculusStreamError extends Error {
45
+ /** The raw line that failed to parse */
46
+ rawLine;
47
+ constructor(rawLine, cause) {
48
+ super(`Failed to parse NDJSON line: ${rawLine}`);
49
+ this.name = "HomunculusStreamError";
50
+ this.rawLine = rawLine;
51
+ if (cause)
52
+ this.cause = cause;
53
+ }
54
+ }
55
+ exports.host = void 0;
56
+ (function (host) {
57
+ let _baseUrl = "http://localhost:3100";
58
+ /**
59
+ * Configures the SDK's base URL for the Desktop Homunculus HTTP server.
60
+ *
61
+ * @param options - Configuration options
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * host.configure({ baseUrl: "http://localhost:4000" });
66
+ * ```
67
+ */
68
+ function configure(options) {
69
+ _baseUrl = options.baseUrl.replace(/\/+$/, "");
70
+ }
71
+ host.configure = configure;
72
+ /** Returns the base URL for the Desktop Homunculus HTTP server. */
73
+ function base() {
74
+ return _baseUrl;
75
+ }
76
+ host.base = base;
77
+ /** Creates a new URL instance pointing to the base server. */
78
+ function baseUrl() {
79
+ return new URL(_baseUrl);
80
+ }
81
+ host.baseUrl = baseUrl;
82
+ /**
83
+ * Creates a URL for the Desktop Homunculus API with optional query parameters.
84
+ *
85
+ * @param path - The API endpoint path (relative to base URL)
86
+ * @param params - Optional query parameters to append to the URL
87
+ * @returns A URL instance ready for use in HTTP requests
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * // Simple path
92
+ * const url = host.createUrl("vrm");
93
+ * // Result: http://localhost:3100/vrm
94
+ *
95
+ * // With query parameters
96
+ * const url = host.createUrl("entities", { name: "VRM", root: 123 });
97
+ * // Result: http://localhost:3100/entities?name=VRM&root=123
98
+ * ```
99
+ */
100
+ function createUrl(path, params) {
101
+ const url = new URL(path, base());
102
+ if (params) {
103
+ Object.entries(params).forEach(([key, value]) => {
104
+ url.searchParams.append(key, String(value));
105
+ });
106
+ }
107
+ return url;
108
+ }
109
+ host.createUrl = createUrl;
110
+ /**
111
+ * Performs a GET request to the specified URL with automatic error handling.
112
+ *
113
+ * @param url - The URL to send the GET request to
114
+ * @returns The Response object if successful
115
+ * @throws {HomunculusApiError} If the response status is >= 400
116
+ *
117
+ * @example
118
+ * ```typescript
119
+ * const response = await host.get(host.createUrl("vrm"));
120
+ * const data = await response.json();
121
+ * ```
122
+ */
123
+ async function get(url) {
124
+ const response = await fetch(url);
125
+ await throwIfError(response);
126
+ return response;
127
+ }
128
+ host.get = get;
129
+ /**
130
+ * Performs a POST request with JSON payload and automatic error handling.
131
+ *
132
+ * @param url - The URL to send the POST request to
133
+ * @param body - Optional request body that will be JSON-serialized
134
+ * @returns The Response object if successful
135
+ * @throws {HomunculusApiError} If the response status is >= 400
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * const response = await host.post(
140
+ * host.createUrl("vrm"),
141
+ * { asset: "my-mod::character.vrm" }
142
+ * );
143
+ * ```
144
+ */
145
+ async function post(url, body) {
146
+ const response = await fetch(url, {
147
+ method: "POST",
148
+ headers: {
149
+ "Content-Type": "application/json"
150
+ },
151
+ body: JSON.stringify(body ?? {})
152
+ });
153
+ await throwIfError(response);
154
+ return response;
155
+ }
156
+ host.post = post;
157
+ /**
158
+ * Performs a PUT request with JSON payload and automatic error handling.
159
+ *
160
+ * @param url - The URL to send the PUT request to
161
+ * @param body - Optional request body that will be JSON-serialized
162
+ * @returns The Response object if successful
163
+ * @throws {HomunculusApiError} If the response status is >= 400
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * await host.put(
168
+ * host.createUrl("vrm/123/state"),
169
+ * { state: "idle" }
170
+ * );
171
+ * ```
172
+ */
173
+ async function put(url, body) {
174
+ const response = await fetch(url, {
175
+ method: "PUT",
176
+ headers: {
177
+ "Content-Type": "application/json"
178
+ },
179
+ body: JSON.stringify(body ?? {})
180
+ });
181
+ await throwIfError(response);
182
+ return response;
183
+ }
184
+ host.put = put;
185
+ /**
186
+ * Performs a PATCH request with JSON payload and automatic error handling.
187
+ *
188
+ * @param url - The URL to send the PATCH request to
189
+ * @param body - Optional request body that will be JSON-serialized
190
+ * @returns The Response object if successful
191
+ * @throws {HomunculusApiError} If the response status is >= 400
192
+ */
193
+ async function patch(url, body) {
194
+ const response = await fetch(url, {
195
+ method: "PATCH",
196
+ headers: {
197
+ "Content-Type": "application/json"
198
+ },
199
+ body: JSON.stringify(body ?? {})
200
+ });
201
+ await throwIfError(response);
202
+ return response;
203
+ }
204
+ host.patch = patch;
205
+ async function deleteMethod(url) {
206
+ const response = await fetch(url, {
207
+ method: "DELETE"
208
+ });
209
+ await throwIfError(response);
210
+ return response;
211
+ }
212
+ host.deleteMethod = deleteMethod;
213
+ /**
214
+ * Performs a POST request and returns an async generator that yields
215
+ * parsed NDJSON objects from the streaming response.
216
+ *
217
+ * @param url - The URL to send the POST request to
218
+ * @param body - Optional request body that will be JSON-serialized
219
+ * @param signal - Optional AbortSignal for cancellation
220
+ * @returns An async generator yielding parsed JSON objects of type T
221
+ * @throws {HomunculusApiError} If the response status is >= 400
222
+ * @throws {HomunculusStreamError} If an NDJSON line cannot be parsed
223
+ *
224
+ * @example
225
+ * ```typescript
226
+ * const stream = host.postStream<MyEvent>(
227
+ * host.createUrl("mods/my-mod/commands/execute"),
228
+ * { command: "build" }
229
+ * );
230
+ * for await (const event of stream) {
231
+ * console.log(event);
232
+ * }
233
+ * ```
234
+ */
235
+ async function* postStream(url, body, signal) {
236
+ const response = await fetch(url, {
237
+ method: "POST",
238
+ headers: {
239
+ "Content-Type": "application/json"
240
+ },
241
+ body: JSON.stringify(body ?? {}),
242
+ signal,
243
+ });
244
+ await throwIfError(response);
245
+ if (!response.body) {
246
+ return;
247
+ }
248
+ const reader = response.body
249
+ .pipeThrough(new TextDecoderStream())
250
+ .getReader();
251
+ let buffer = "";
252
+ try {
253
+ for (;;) {
254
+ const { done, value } = await reader.read();
255
+ if (done)
256
+ break;
257
+ buffer += value;
258
+ const lines = buffer.split("\n");
259
+ // Keep the last (possibly incomplete) chunk in the buffer
260
+ buffer = lines.pop();
261
+ for (const line of lines) {
262
+ const trimmed = line.trim();
263
+ if (trimmed.length === 0)
264
+ continue;
265
+ try {
266
+ yield JSON.parse(trimmed);
267
+ }
268
+ catch (e) {
269
+ throw new HomunculusStreamError(trimmed, e);
270
+ }
271
+ }
272
+ }
273
+ // Process any remaining data in the buffer
274
+ const trimmed = buffer.trim();
275
+ if (trimmed.length > 0) {
276
+ try {
277
+ yield JSON.parse(trimmed);
278
+ }
279
+ catch (e) {
280
+ throw new HomunculusStreamError(trimmed, e);
281
+ }
282
+ }
283
+ }
284
+ finally {
285
+ reader.releaseLock();
286
+ }
287
+ }
288
+ host.postStream = postStream;
289
+ })(exports.host || (exports.host = {}));
290
+ async function throwIfError(response) {
291
+ if (!response.ok) {
292
+ throw new HomunculusApiError(response.status, response.url, await response.text());
293
+ }
294
+ }
295
+
296
+ exports.HomunculusApiError = HomunculusApiError;
297
+ exports.HomunculusStreamError = HomunculusStreamError;
package/dist/host.js ADDED
@@ -0,0 +1,294 @@
1
+ /**
2
+ * Host API namespace for low-level HTTP communication with the Desktop Homunculus server.
3
+ *
4
+ * This module provides the foundational HTTP client functionality used internally
5
+ * by all other SDK modules. It handles the base URL configuration, URL construction,
6
+ * and HTTP methods with automatic error handling.
7
+ *
8
+ * **Note:** This module is primarily for internal SDK use. Most developers should
9
+ * use the higher-level namespaces like `vrm`, `signals`, etc.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // Internal SDK usage (you typically won't need this directly)
14
+ * const response = await host.get(host.createUrl("vrm"));
15
+ * const vrms = await response.json();
16
+ *
17
+ * // URL construction with parameters
18
+ * const url = host.createUrl("vrm", { name: "MyCharacter" });
19
+ * // Results in: http://localhost:3100/vrm?name=MyCharacter
20
+ *
21
+ * // Configure the base URL (e.g., from an MCP server)
22
+ * host.configure({ baseUrl: "http://localhost:4000" });
23
+ * ```
24
+ */
25
+ /** Error thrown when the Homunculus HTTP API returns a non-OK response. */
26
+ class HomunculusApiError extends Error {
27
+ /** HTTP status code (e.g. 404, 500) */
28
+ statusCode;
29
+ /** The request endpoint URL */
30
+ endpoint;
31
+ /** The response body text */
32
+ body;
33
+ constructor(statusCode, endpoint, body) {
34
+ super(`${endpoint}: ${statusCode} ${body}`);
35
+ this.name = "HomunculusApiError";
36
+ this.statusCode = statusCode;
37
+ this.endpoint = endpoint;
38
+ this.body = body;
39
+ }
40
+ }
41
+ /** Error thrown when an NDJSON stream contains malformed data. */
42
+ class HomunculusStreamError extends Error {
43
+ /** The raw line that failed to parse */
44
+ rawLine;
45
+ constructor(rawLine, cause) {
46
+ super(`Failed to parse NDJSON line: ${rawLine}`);
47
+ this.name = "HomunculusStreamError";
48
+ this.rawLine = rawLine;
49
+ if (cause)
50
+ this.cause = cause;
51
+ }
52
+ }
53
+ var host;
54
+ (function (host) {
55
+ let _baseUrl = "http://localhost:3100";
56
+ /**
57
+ * Configures the SDK's base URL for the Desktop Homunculus HTTP server.
58
+ *
59
+ * @param options - Configuration options
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * host.configure({ baseUrl: "http://localhost:4000" });
64
+ * ```
65
+ */
66
+ function configure(options) {
67
+ _baseUrl = options.baseUrl.replace(/\/+$/, "");
68
+ }
69
+ host.configure = configure;
70
+ /** Returns the base URL for the Desktop Homunculus HTTP server. */
71
+ function base() {
72
+ return _baseUrl;
73
+ }
74
+ host.base = base;
75
+ /** Creates a new URL instance pointing to the base server. */
76
+ function baseUrl() {
77
+ return new URL(_baseUrl);
78
+ }
79
+ host.baseUrl = baseUrl;
80
+ /**
81
+ * Creates a URL for the Desktop Homunculus API with optional query parameters.
82
+ *
83
+ * @param path - The API endpoint path (relative to base URL)
84
+ * @param params - Optional query parameters to append to the URL
85
+ * @returns A URL instance ready for use in HTTP requests
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * // Simple path
90
+ * const url = host.createUrl("vrm");
91
+ * // Result: http://localhost:3100/vrm
92
+ *
93
+ * // With query parameters
94
+ * const url = host.createUrl("entities", { name: "VRM", root: 123 });
95
+ * // Result: http://localhost:3100/entities?name=VRM&root=123
96
+ * ```
97
+ */
98
+ function createUrl(path, params) {
99
+ const url = new URL(path, base());
100
+ if (params) {
101
+ Object.entries(params).forEach(([key, value]) => {
102
+ url.searchParams.append(key, String(value));
103
+ });
104
+ }
105
+ return url;
106
+ }
107
+ host.createUrl = createUrl;
108
+ /**
109
+ * Performs a GET request to the specified URL with automatic error handling.
110
+ *
111
+ * @param url - The URL to send the GET request to
112
+ * @returns The Response object if successful
113
+ * @throws {HomunculusApiError} If the response status is >= 400
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * const response = await host.get(host.createUrl("vrm"));
118
+ * const data = await response.json();
119
+ * ```
120
+ */
121
+ async function get(url) {
122
+ const response = await fetch(url);
123
+ await throwIfError(response);
124
+ return response;
125
+ }
126
+ host.get = get;
127
+ /**
128
+ * Performs a POST request with JSON payload and automatic error handling.
129
+ *
130
+ * @param url - The URL to send the POST request to
131
+ * @param body - Optional request body that will be JSON-serialized
132
+ * @returns The Response object if successful
133
+ * @throws {HomunculusApiError} If the response status is >= 400
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * const response = await host.post(
138
+ * host.createUrl("vrm"),
139
+ * { asset: "my-mod::character.vrm" }
140
+ * );
141
+ * ```
142
+ */
143
+ async function post(url, body) {
144
+ const response = await fetch(url, {
145
+ method: "POST",
146
+ headers: {
147
+ "Content-Type": "application/json"
148
+ },
149
+ body: JSON.stringify(body ?? {})
150
+ });
151
+ await throwIfError(response);
152
+ return response;
153
+ }
154
+ host.post = post;
155
+ /**
156
+ * Performs a PUT request with JSON payload and automatic error handling.
157
+ *
158
+ * @param url - The URL to send the PUT request to
159
+ * @param body - Optional request body that will be JSON-serialized
160
+ * @returns The Response object if successful
161
+ * @throws {HomunculusApiError} If the response status is >= 400
162
+ *
163
+ * @example
164
+ * ```typescript
165
+ * await host.put(
166
+ * host.createUrl("vrm/123/state"),
167
+ * { state: "idle" }
168
+ * );
169
+ * ```
170
+ */
171
+ async function put(url, body) {
172
+ const response = await fetch(url, {
173
+ method: "PUT",
174
+ headers: {
175
+ "Content-Type": "application/json"
176
+ },
177
+ body: JSON.stringify(body ?? {})
178
+ });
179
+ await throwIfError(response);
180
+ return response;
181
+ }
182
+ host.put = put;
183
+ /**
184
+ * Performs a PATCH request with JSON payload and automatic error handling.
185
+ *
186
+ * @param url - The URL to send the PATCH request to
187
+ * @param body - Optional request body that will be JSON-serialized
188
+ * @returns The Response object if successful
189
+ * @throws {HomunculusApiError} If the response status is >= 400
190
+ */
191
+ async function patch(url, body) {
192
+ const response = await fetch(url, {
193
+ method: "PATCH",
194
+ headers: {
195
+ "Content-Type": "application/json"
196
+ },
197
+ body: JSON.stringify(body ?? {})
198
+ });
199
+ await throwIfError(response);
200
+ return response;
201
+ }
202
+ host.patch = patch;
203
+ async function deleteMethod(url) {
204
+ const response = await fetch(url, {
205
+ method: "DELETE"
206
+ });
207
+ await throwIfError(response);
208
+ return response;
209
+ }
210
+ host.deleteMethod = deleteMethod;
211
+ /**
212
+ * Performs a POST request and returns an async generator that yields
213
+ * parsed NDJSON objects from the streaming response.
214
+ *
215
+ * @param url - The URL to send the POST request to
216
+ * @param body - Optional request body that will be JSON-serialized
217
+ * @param signal - Optional AbortSignal for cancellation
218
+ * @returns An async generator yielding parsed JSON objects of type T
219
+ * @throws {HomunculusApiError} If the response status is >= 400
220
+ * @throws {HomunculusStreamError} If an NDJSON line cannot be parsed
221
+ *
222
+ * @example
223
+ * ```typescript
224
+ * const stream = host.postStream<MyEvent>(
225
+ * host.createUrl("mods/my-mod/commands/execute"),
226
+ * { command: "build" }
227
+ * );
228
+ * for await (const event of stream) {
229
+ * console.log(event);
230
+ * }
231
+ * ```
232
+ */
233
+ async function* postStream(url, body, signal) {
234
+ const response = await fetch(url, {
235
+ method: "POST",
236
+ headers: {
237
+ "Content-Type": "application/json"
238
+ },
239
+ body: JSON.stringify(body ?? {}),
240
+ signal,
241
+ });
242
+ await throwIfError(response);
243
+ if (!response.body) {
244
+ return;
245
+ }
246
+ const reader = response.body
247
+ .pipeThrough(new TextDecoderStream())
248
+ .getReader();
249
+ let buffer = "";
250
+ try {
251
+ for (;;) {
252
+ const { done, value } = await reader.read();
253
+ if (done)
254
+ break;
255
+ buffer += value;
256
+ const lines = buffer.split("\n");
257
+ // Keep the last (possibly incomplete) chunk in the buffer
258
+ buffer = lines.pop();
259
+ for (const line of lines) {
260
+ const trimmed = line.trim();
261
+ if (trimmed.length === 0)
262
+ continue;
263
+ try {
264
+ yield JSON.parse(trimmed);
265
+ }
266
+ catch (e) {
267
+ throw new HomunculusStreamError(trimmed, e);
268
+ }
269
+ }
270
+ }
271
+ // Process any remaining data in the buffer
272
+ const trimmed = buffer.trim();
273
+ if (trimmed.length > 0) {
274
+ try {
275
+ yield JSON.parse(trimmed);
276
+ }
277
+ catch (e) {
278
+ throw new HomunculusStreamError(trimmed, e);
279
+ }
280
+ }
281
+ }
282
+ finally {
283
+ reader.releaseLock();
284
+ }
285
+ }
286
+ host.postStream = postStream;
287
+ })(host || (host = {}));
288
+ async function throwIfError(response) {
289
+ if (!response.ok) {
290
+ throw new HomunculusApiError(response.status, response.url, await response.text());
291
+ }
292
+ }
293
+
294
+ export { HomunculusApiError, HomunculusStreamError, host };
package/dist/index.cjs ADDED
@@ -0,0 +1,98 @@
1
+ 'use strict';
2
+
3
+ var coordinates = require('./coordinates.cjs');
4
+ var displays = require('./displays.cjs');
5
+ var audio = require('./audio.cjs');
6
+ var effects = require('./effects.cjs');
7
+ var host = require('./host.cjs');
8
+ var preferences = require('./preferences.cjs');
9
+ var settings = require('./settings.cjs');
10
+ var shadowPanel = require('./shadowPanel.cjs');
11
+ var vrm = require('./vrm.cjs');
12
+ var speech = require('./speech.cjs');
13
+ var webviews = require('./webviews.cjs');
14
+ var signals = require('./signals.cjs');
15
+ var entities = require('./entities.cjs');
16
+ var app = require('./app.cjs');
17
+ var mods = require('./mods.cjs');
18
+ var assets = require('./assets.cjs');
19
+ var utils = require('./utils.cjs');
20
+
21
+
22
+
23
+ Object.defineProperty(exports, "coordinates", {
24
+ enumerable: true,
25
+ get: function () { return coordinates.coordinates; }
26
+ });
27
+ Object.defineProperty(exports, "displays", {
28
+ enumerable: true,
29
+ get: function () { return displays.displays; }
30
+ });
31
+ Object.defineProperty(exports, "audio", {
32
+ enumerable: true,
33
+ get: function () { return audio.audio; }
34
+ });
35
+ Object.defineProperty(exports, "effects", {
36
+ enumerable: true,
37
+ get: function () { return effects.effects; }
38
+ });
39
+ exports.HomunculusApiError = host.HomunculusApiError;
40
+ exports.HomunculusStreamError = host.HomunculusStreamError;
41
+ Object.defineProperty(exports, "host", {
42
+ enumerable: true,
43
+ get: function () { return host.host; }
44
+ });
45
+ Object.defineProperty(exports, "preferences", {
46
+ enumerable: true,
47
+ get: function () { return preferences.preferences; }
48
+ });
49
+ Object.defineProperty(exports, "settings", {
50
+ enumerable: true,
51
+ get: function () { return settings.settings; }
52
+ });
53
+ Object.defineProperty(exports, "shadowPanel", {
54
+ enumerable: true,
55
+ get: function () { return shadowPanel.shadowPanel; }
56
+ });
57
+ exports.Vrm = vrm.Vrm;
58
+ exports.VrmEventSource = vrm.VrmEventSource;
59
+ Object.defineProperty(exports, "repeat", {
60
+ enumerable: true,
61
+ get: function () { return vrm.repeat; }
62
+ });
63
+ Object.defineProperty(exports, "speech", {
64
+ enumerable: true,
65
+ get: function () { return speech.speech; }
66
+ });
67
+ exports.Webview = webviews.Webview;
68
+ exports.isWebviewSourceHtml = webviews.isWebviewSourceHtml;
69
+ exports.isWebviewSourceInfoHtml = webviews.isWebviewSourceInfoHtml;
70
+ exports.isWebviewSourceInfoLocal = webviews.isWebviewSourceInfoLocal;
71
+ exports.isWebviewSourceInfoUrl = webviews.isWebviewSourceInfoUrl;
72
+ exports.isWebviewSourceLocal = webviews.isWebviewSourceLocal;
73
+ exports.isWebviewSourceUrl = webviews.isWebviewSourceUrl;
74
+ Object.defineProperty(exports, "webviewSource", {
75
+ enumerable: true,
76
+ get: function () { return webviews.webviewSource; }
77
+ });
78
+ Object.defineProperty(exports, "signals", {
79
+ enumerable: true,
80
+ get: function () { return signals.signals; }
81
+ });
82
+ Object.defineProperty(exports, "entities", {
83
+ enumerable: true,
84
+ get: function () { return entities.entities; }
85
+ });
86
+ Object.defineProperty(exports, "app", {
87
+ enumerable: true,
88
+ get: function () { return app.app; }
89
+ });
90
+ Object.defineProperty(exports, "mods", {
91
+ enumerable: true,
92
+ get: function () { return mods.mods; }
93
+ });
94
+ Object.defineProperty(exports, "assets", {
95
+ enumerable: true,
96
+ get: function () { return assets.assets; }
97
+ });
98
+ exports.sleep = utils.sleep;