multyx-client 0.1.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.
@@ -0,0 +1,356 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Controller = void 0;
4
+ const message_1 = require("./message");
5
+ class Controller {
6
+ constructor(ws) {
7
+ this.listening = new Set();
8
+ this.ws = ws;
9
+ this.preventDefault = false;
10
+ this.keys = {};
11
+ this.mouse = {
12
+ x: NaN,
13
+ y: NaN,
14
+ down: false,
15
+ centerX: 0,
16
+ centerY: 0,
17
+ scaleX: 1,
18
+ scaleY: 1
19
+ };
20
+ document.addEventListener('keydown', e => {
21
+ if (this.preventDefault)
22
+ e.preventDefault;
23
+ const key = e.key.toLowerCase();
24
+ // When holding down key
25
+ if (this.keys[key] && this.listening.has('keyhold')) {
26
+ this.relayInput('keyhold', { code: key });
27
+ }
28
+ if (this.keys[e.code] && this.listening.has('keyhold')) {
29
+ this.relayInput('keyhold', { code: e.code });
30
+ }
31
+ // Change in key state
32
+ if (this.listening.has(key) && !this.keys[key]) {
33
+ this.relayInput('keydown', { code: e.key });
34
+ }
35
+ if (this.listening.has(e.code) && !this.keys[e.code]) {
36
+ this.relayInput('keydown', { code: e.code });
37
+ }
38
+ this.keys[key] = true;
39
+ this.keys[e.code] = true;
40
+ });
41
+ document.addEventListener('keyup', e => {
42
+ if (this.preventDefault)
43
+ e.preventDefault;
44
+ const key = e.key.toLowerCase();
45
+ delete this.keys[key];
46
+ delete this.keys[e.code];
47
+ if (this.listening.has(key))
48
+ this.relayInput('keyup', { code: key });
49
+ if (this.listening.has(e.code))
50
+ this.relayInput('keyup', { code: e.code });
51
+ });
52
+ // Mouse input events
53
+ document.addEventListener('mousedown', e => {
54
+ if (this.preventDefault)
55
+ e.preventDefault;
56
+ if (this.mouseGetter) {
57
+ const mouse = this.mouseGetter();
58
+ this.mouse.x = mouse.x;
59
+ this.mouse.y = mouse.y;
60
+ }
61
+ else {
62
+ this.mouse.x = (e.clientX - this.mouse.centerX) / this.mouse.scaleX;
63
+ this.mouse.y = (e.clientY - this.mouse.centerY) / this.mouse.scaleY;
64
+ }
65
+ this.mouse.down = true;
66
+ if (this.listening.has('mousedown'))
67
+ this.relayInput('mousedown', {
68
+ x: this.mouse.x, y: this.mouse.y
69
+ });
70
+ });
71
+ document.addEventListener('mouseup', e => {
72
+ if (this.preventDefault)
73
+ e.preventDefault;
74
+ if (this.mouseGetter) {
75
+ const mouse = this.mouseGetter();
76
+ this.mouse.x = mouse.x;
77
+ this.mouse.y = mouse.y;
78
+ }
79
+ else {
80
+ this.mouse.x = (e.clientX - this.mouse.centerX) / this.mouse.scaleX;
81
+ this.mouse.y = (e.clientY - this.mouse.centerY) / this.mouse.scaleY;
82
+ }
83
+ this.mouse.down = false;
84
+ if (this.listening.has('mouseup'))
85
+ this.relayInput('mouseup', {
86
+ x: this.mouse.x, y: this.mouse.y
87
+ });
88
+ });
89
+ document.addEventListener('mousemove', e => {
90
+ if (this.preventDefault)
91
+ e.preventDefault;
92
+ if (this.mouseGetter) {
93
+ const mouse = this.mouseGetter();
94
+ this.mouse.x = mouse.x;
95
+ this.mouse.y = mouse.y;
96
+ }
97
+ else {
98
+ this.mouse.x = (e.clientX - this.mouse.centerX) / this.mouse.scaleX;
99
+ this.mouse.y = (e.clientY - this.mouse.centerY) / this.mouse.scaleY;
100
+ }
101
+ if (this.listening.has('mousemove'))
102
+ this.relayInput('mousemove', {
103
+ x: this.mouse.x, y: this.mouse.y
104
+ });
105
+ });
106
+ }
107
+ /**
108
+ * Map the canvas to specified top left and bottom right positions
109
+ * @param canvas HTML canvas element
110
+ * @param canvasContext 2D rendering context for canvas
111
+ * @param top Canvas position to correspond to top of canvas
112
+ * @param left Canvas position to correspond to left of canvas
113
+ * @param bottom Canvas position to correspond to bottom of canvas
114
+ * @param right Canvas position to correspond to right of canvas
115
+ * @param anchor Anchor the origin at a specific spot on the canvas
116
+ */
117
+ mapCanvasPosition(canvas, position) {
118
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
119
+ const t = 'top' in position;
120
+ const b = 'bottom' in position;
121
+ const l = 'left' in position;
122
+ const r = 'right' in position;
123
+ const a = position.anchor;
124
+ const bounding = canvas.getBoundingClientRect();
125
+ const error = (included, ...pieces) => {
126
+ const p1 = included ? "Cannot include value for " : "Must include value for ";
127
+ const p2 = pieces.length == 1 ? pieces[0] : pieces.slice(0, -1).join(', ') + (included ? ' and ' : ' or ') + pieces.slice(-1)[0];
128
+ const p3 = a ? " if anchoring at " + a : " if not anchoring";
129
+ console.error(p1 + p2 + p3);
130
+ };
131
+ const wToH = bounding.width / bounding.height;
132
+ const hToW = bounding.height / bounding.width;
133
+ if (Number.isNaN(wToH) || Number.isNaN(hToW)) {
134
+ console.error("Canvas element bounding box is flat, canvas must be present on the screen");
135
+ }
136
+ // mb bruh jus trust it works
137
+ if (!a) {
138
+ if (!t && !b)
139
+ return error(false, 'top', 'bottom');
140
+ else if (!b)
141
+ position.bottom = position.top + canvas.height;
142
+ else if (!t)
143
+ position.top = position.bottom - canvas.height;
144
+ if (!l && !r)
145
+ return error(false, 'left', 'right');
146
+ else if (!r)
147
+ position.right = position.left + canvas.width;
148
+ else if (!l)
149
+ position.left = position.right - canvas.width;
150
+ }
151
+ else if (a == 'center') {
152
+ if (t && b && position.top !== -position.bottom
153
+ || l && r && position.left !== -position.right)
154
+ return error(true, 'top', 'bottom', 'left', 'right');
155
+ if (t) {
156
+ position.left = l ? position.left : r ? -position.right : -Math.abs(wToH * position.top);
157
+ position.right = l ? -position.left : r ? position.right : Math.abs(wToH * position.top);
158
+ position.bottom = -position.top;
159
+ }
160
+ else if (b) {
161
+ position.left = l ? position.left : r ? -position.right : -Math.abs(wToH * position.bottom);
162
+ position.right = l ? -position.left : r ? position.right : Math.abs(wToH * position.bottom);
163
+ position.top = -position.bottom;
164
+ }
165
+ else if (l) {
166
+ position.top = t ? position.top : b ? -position.bottom : -Math.abs(hToW * position.left);
167
+ position.bottom = t ? -position.top : b ? position.bottom : Math.abs(hToW * position.left);
168
+ position.right = -position.left;
169
+ }
170
+ else if (r) {
171
+ position.top = t ? position.top : b ? -position.bottom : -Math.abs(hToW * position.right);
172
+ position.bottom = t ? -position.top : b ? position.bottom : Math.abs(hToW * position.right);
173
+ position.left = -position.right;
174
+ }
175
+ }
176
+ else if (a == 'bottom') {
177
+ if (!l && !r && !t)
178
+ return error(false, 'left', 'right', 'top');
179
+ if (position.bottom)
180
+ return error(true, 'bottom');
181
+ position.bottom = 0;
182
+ if (l) {
183
+ (_a = position.top) !== null && _a !== void 0 ? _a : (position.top = Math.abs(hToW * position.left * 2));
184
+ (_b = position.right) !== null && _b !== void 0 ? _b : (position.right = -position.left);
185
+ }
186
+ else if (r) {
187
+ (_c = position.top) !== null && _c !== void 0 ? _c : (position.top = Math.abs(hToW * position.right * 2));
188
+ (_d = position.left) !== null && _d !== void 0 ? _d : (position.left = -position.right);
189
+ }
190
+ else {
191
+ position.left = -Math.abs(wToH * position.top / 2);
192
+ position.right = -position.left;
193
+ }
194
+ }
195
+ else if (a == 'top') {
196
+ if (!l && !r && !b)
197
+ return error(false, 'left', 'right', 'bottom');
198
+ if (position.top)
199
+ return error(true, 'top');
200
+ position.top = 0;
201
+ if (l) {
202
+ (_e = position.bottom) !== null && _e !== void 0 ? _e : (position.bottom = Math.abs(hToW * position.left * 2));
203
+ (_f = position.right) !== null && _f !== void 0 ? _f : (position.right = -position.left);
204
+ }
205
+ else if (r) {
206
+ (_g = position.bottom) !== null && _g !== void 0 ? _g : (position.bottom = Math.abs(hToW * position.right * 2));
207
+ (_h = position.left) !== null && _h !== void 0 ? _h : (position.left = -position.right);
208
+ }
209
+ else {
210
+ position.left = -Math.abs(wToH * position.bottom / 2);
211
+ position.right = -position.left;
212
+ }
213
+ }
214
+ else if (a == 'left') {
215
+ if (!t && !b && !r)
216
+ return error(false, 'top', 'bottom', 'right');
217
+ if (l)
218
+ return error(true, 'left');
219
+ position.left = 0;
220
+ if (t) {
221
+ (_j = position.right) !== null && _j !== void 0 ? _j : (position.right = -Math.abs(wToH * position.top * 2));
222
+ (_k = position.bottom) !== null && _k !== void 0 ? _k : (position.bottom = -position.top);
223
+ }
224
+ else if (b) {
225
+ (_l = position.right) !== null && _l !== void 0 ? _l : (position.right = Math.abs(wToH * position.bottom * 2));
226
+ (_m = position.top) !== null && _m !== void 0 ? _m : (position.top = -position.bottom);
227
+ }
228
+ else {
229
+ position.top = -Math.abs(hToW * position.right / 2);
230
+ position.bottom = -position.top;
231
+ }
232
+ }
233
+ else if (a == 'right') {
234
+ if (!t && !b && !l)
235
+ return error(false, 'top', 'bottom', 'left');
236
+ if (r)
237
+ return error(true, 'right');
238
+ position.right = 0;
239
+ if (t) {
240
+ (_o = position.left) !== null && _o !== void 0 ? _o : (position.left = -Math.abs(wToH * position.top * 2));
241
+ (_p = position.bottom) !== null && _p !== void 0 ? _p : (position.bottom = -position.top);
242
+ }
243
+ else if (b) {
244
+ (_q = position.left) !== null && _q !== void 0 ? _q : (position.left = Math.abs(wToH * position.bottom * 2));
245
+ (_r = position.top) !== null && _r !== void 0 ? _r : (position.top = -position.bottom);
246
+ }
247
+ else {
248
+ position.top = -Math.abs(hToW * position.right / 2);
249
+ position.bottom = -position.top;
250
+ }
251
+ }
252
+ else if (a == 'topleft') {
253
+ if (!r && !b)
254
+ return error(false, 'right', 'bottom');
255
+ if (l || t)
256
+ return error(true, 'left', 'top');
257
+ position.left = position.top = 0;
258
+ if (r)
259
+ position.bottom = Math.abs(hToW * position.right);
260
+ else
261
+ position.right = Math.abs(wToH * position.bottom);
262
+ }
263
+ else if (a == 'topright') {
264
+ if (!l && !b)
265
+ return error(false, 'left', 'bottom');
266
+ if (r || t)
267
+ return error(true, 'right', 'top');
268
+ position.right = position.top = 0;
269
+ if (l)
270
+ position.bottom = Math.abs(hToW * position.left);
271
+ else
272
+ position.left = Math.abs(wToH * position.bottom);
273
+ }
274
+ else if (a == 'bottomleft') {
275
+ if (!r && !t)
276
+ return error(false, 'right', 'top');
277
+ if (b || l)
278
+ return error(true, 'bottom', 'left');
279
+ position.left = position.bottom = 0;
280
+ if (r)
281
+ position.top = Math.abs(hToW * position.right);
282
+ else
283
+ position.right = Math.abs(wToH * position.top);
284
+ }
285
+ else if (a == 'bottomright') {
286
+ if (!t && !l)
287
+ return error(false, 'top', 'left');
288
+ if (r || b)
289
+ return error(true, 'bottom', 'right');
290
+ position.right = position.bottom = 0;
291
+ if (l)
292
+ position.top = Math.abs(hToW * position.left);
293
+ else
294
+ position.left = Math.abs(wToH * position.top);
295
+ }
296
+ const ctx = canvas.getContext("2d");
297
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
298
+ canvas.width = Math.floor(Math.abs(position.right - position.left));
299
+ canvas.height = Math.floor(Math.abs(position.bottom - position.top));
300
+ if (position.right < position.left)
301
+ ctx.scale(-1, 1);
302
+ if (position.top > position.bottom)
303
+ ctx.scale(1, -1);
304
+ ctx.translate(-position.left, -position.top);
305
+ }
306
+ /**
307
+ * @param centerX Anchor x-value corresponding to mouse position x-value of 0
308
+ * @param centerY Anchor y-value corresponding to mouse position y-value of 0
309
+ * @param anchor HTML Element to read mouse position relative to
310
+ * @param scaleX Number of anchor pixels corresponding to a mouse position x-value change of 1
311
+ * @param scaleY Number of anchor pixels corresponding to a mouse position y-value change of 1
312
+ */
313
+ mapMousePosition(centerX, centerY, anchor = document.body, scaleX = 1, scaleY = scaleX) {
314
+ const ratioX = window.innerWidth / (anchor instanceof HTMLCanvasElement
315
+ ? anchor.width
316
+ : anchor.clientWidth);
317
+ const ratioY = window.innerHeight / (anchor instanceof HTMLCanvasElement
318
+ ? anchor.height
319
+ : anchor.clientHeight);
320
+ const bounding = anchor.getBoundingClientRect();
321
+ this.mouse.centerX = bounding.left + centerX * ratioX;
322
+ this.mouse.centerY = bounding.top + centerY * ratioY;
323
+ this.mouse.scaleX = scaleX * ratioX;
324
+ this.mouse.scaleY = scaleY * ratioY;
325
+ }
326
+ /**
327
+ * Map mouse position to the corresponding canvas coordinates on screen
328
+ * @param canvas Canvas element in DOM
329
+ */
330
+ mapMouseToCanvas(canvas) {
331
+ const ctx = canvas.getContext("2d");
332
+ const transform = ctx.getTransform();
333
+ const bounding = canvas.getBoundingClientRect();
334
+ // Ratio between canvas scale to unit pixels
335
+ const canvasRatioX = bounding.width / canvas.width;
336
+ const canvasRatioY = bounding.height / canvas.height;
337
+ this.mouse.centerX = bounding.left + transform.e * canvasRatioX;
338
+ this.mouse.centerY = bounding.top + transform.f * canvasRatioY;
339
+ this.mouse.scaleX = canvasRatioX * transform.a;
340
+ this.mouse.scaleY = canvasRatioY * transform.d;
341
+ }
342
+ /**
343
+ * Utilize mouse coordinates of another object
344
+ * @param mouseGetter Callback that returns the mouse coordinates at any given time
345
+ */
346
+ setMouseAs(mouseGetter) {
347
+ this.mouseGetter = mouseGetter;
348
+ }
349
+ relayInput(input, data) {
350
+ if (this.ws.readyState !== 1) {
351
+ throw new Error('Websocket connection is ' + (this.ws.readyState == 2 ? 'closing' : 'closed'));
352
+ }
353
+ this.ws.send(message_1.Message.Native(Object.assign({ instruction: 'input', input: input }, (data ? { data } : {}))));
354
+ }
355
+ }
356
+ exports.Controller = Controller;
package/dist/index.js ADDED
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const message_1 = require("./message");
4
+ const utils_1 = require("./utils");
5
+ const controller_1 = require("./controller");
6
+ const items_1 = require("./items");
7
+ const options_1 = require("./options");
8
+ class Multyx {
9
+ constructor(options = {}, callback) {
10
+ this.options = Object.assign(Object.assign({}, options_1.DefaultOptions), options);
11
+ const url = `ws${this.options.secure ? 's' : ''}://${this.options.uri}:${this.options.port}/`;
12
+ this.ws = new WebSocket(url);
13
+ this.ping = 0;
14
+ this.events = new Map();
15
+ this.self = {};
16
+ this.all = {};
17
+ this.teams = {};
18
+ this.clients = {};
19
+ this.controller = new controller_1.Controller(this.ws);
20
+ this.listenerQueue = [];
21
+ callback === null || callback === void 0 ? void 0 : callback();
22
+ this.ws.onmessage = event => {
23
+ var _a, _b, _c;
24
+ const msg = message_1.Message.Parse(event.data);
25
+ this.ping = 2 * (Date.now() - msg.time);
26
+ if (msg.native) {
27
+ this.parseNativeEvent(msg);
28
+ (_a = this.events.get(Multyx.Native)) === null || _a === void 0 ? void 0 : _a.forEach(cb => cb(msg));
29
+ }
30
+ else if (msg.name in this.events) {
31
+ this.events[msg.name](msg.data);
32
+ (_b = this.events.get(Multyx.Custom)) === null || _b === void 0 ? void 0 : _b.forEach(cb => cb(msg));
33
+ }
34
+ (_c = this.events.get(Multyx.Any)) === null || _c === void 0 ? void 0 : _c.forEach(cb => cb(msg));
35
+ };
36
+ }
37
+ on(name, callback) {
38
+ var _a;
39
+ const events = (_a = this.events.get(name)) !== null && _a !== void 0 ? _a : [];
40
+ events.push(callback);
41
+ this.events.set(name, events);
42
+ }
43
+ send(name, data, expectResponse = false) {
44
+ if (name[0] === '_')
45
+ name = '_' + name;
46
+ this.ws.send(message_1.Message.Create(name, data));
47
+ if (!expectResponse)
48
+ return;
49
+ return new Promise(res => this.events.set(Symbol.for("_" + name), [res]));
50
+ }
51
+ /**
52
+ * Loop over a function
53
+ * @param callback Function to call on a loop
54
+ * @param timesPerSecond Recommended to leave blank. Number of times to loop in each second, if undefined, use requestAnimationFrame
55
+ */
56
+ loop(callback, timesPerSecond) {
57
+ if (timesPerSecond) {
58
+ this.on(Multyx.Start, () => setInterval(callback, Math.round(1000 / timesPerSecond)));
59
+ }
60
+ else {
61
+ const caller = () => {
62
+ callback();
63
+ requestAnimationFrame(caller);
64
+ };
65
+ this.on(Multyx.Start, () => requestAnimationFrame(caller));
66
+ }
67
+ }
68
+ /**
69
+ * Create a callback function that gets called for any current or future client
70
+ * @param callbackfn Function to call for every client
71
+ */
72
+ forAll(callback) {
73
+ this.on(Multyx.Start, () => {
74
+ this.teams.all.clients.forAll((uuid) => callback(this.clients[uuid]));
75
+ });
76
+ this.on(Multyx.Connection, callback);
77
+ }
78
+ parseNativeEvent(msg) {
79
+ var _a, _b, _c, _d;
80
+ if (this.options.logUpdateFrame)
81
+ console.log(msg);
82
+ for (const update of msg.data) {
83
+ switch (update.instruction) {
84
+ // Initialization
85
+ case 'init': {
86
+ this.initialize(update);
87
+ for (const listener of (_a = this.events.get(Multyx.Start)) !== null && _a !== void 0 ? _a : []) {
88
+ this.listenerQueue.push(() => listener(update));
89
+ }
90
+ // Clear start event as it will never be called again
91
+ if (this.events.has(Multyx.Start))
92
+ this.events.get(Multyx.Start).length = 0;
93
+ break;
94
+ }
95
+ // Client or team data edit
96
+ case 'edit': {
97
+ this.parseEdit(update);
98
+ for (const listener of (_b = this.events.get(Multyx.Edit)) !== null && _b !== void 0 ? _b : []) {
99
+ this.listenerQueue.push(() => listener(update));
100
+ }
101
+ break;
102
+ }
103
+ // Other data change
104
+ case 'self': {
105
+ this.parseSelf(update);
106
+ break;
107
+ }
108
+ // Connection
109
+ case 'conn': {
110
+ this.clients[update.uuid] = new items_1.MultyxClientObject(this, update.data, [update.uuid], false);
111
+ for (const listener of (_c = this.events.get(Multyx.Connection)) !== null && _c !== void 0 ? _c : []) {
112
+ this.listenerQueue.push(() => listener(this.clients[update.uuid]));
113
+ }
114
+ break;
115
+ }
116
+ // Disconnection
117
+ case 'dcon': {
118
+ for (const listener of (_d = this.events.get(Multyx.Disconnect)) !== null && _d !== void 0 ? _d : []) {
119
+ const clientValue = this.clients[update.client].value;
120
+ this.listenerQueue.push(() => listener(clientValue));
121
+ }
122
+ delete this.clients[update.client];
123
+ break;
124
+ }
125
+ // Response to client
126
+ case 'resp': {
127
+ const promiseResolve = this.events.get(Symbol.for("_" + update.name))[0];
128
+ promiseResolve(update.response);
129
+ break;
130
+ }
131
+ default: {
132
+ if (this.options.verbose) {
133
+ console.error("Server error: Unknown native Multyx instruction");
134
+ }
135
+ }
136
+ }
137
+ }
138
+ this.listenerQueue.forEach(x => x());
139
+ this.listenerQueue.length = 0;
140
+ }
141
+ initialize(update) {
142
+ this.uuid = update.client.uuid;
143
+ this.joinTime = update.client.joinTime;
144
+ this.controller.listening = new Set(update.client.controller);
145
+ // Create MultyxClientObject for all teams
146
+ this.teams = new items_1.MultyxClientObject(this, {}, [], true);
147
+ for (const team of Object.keys(update.teams)) {
148
+ this.teams[team] = new utils_1.EditWrapper(update.teams[team]);
149
+ }
150
+ this.all = this.teams['all'];
151
+ // Create MultyxClientObject for all clients
152
+ this.clients = {};
153
+ for (const [uuid, client] of Object.entries(update.clients)) {
154
+ if (uuid == this.uuid)
155
+ continue;
156
+ this.clients[uuid] = new items_1.MultyxClientObject(this, new utils_1.EditWrapper(client), [uuid], false);
157
+ }
158
+ ;
159
+ const client = new items_1.MultyxClientObject(this, new utils_1.EditWrapper(update.client.self), [this.uuid], true);
160
+ this.self = client;
161
+ this.clients[this.uuid] = client;
162
+ // Apply all constraints on self and teams
163
+ for (const [uuid, table] of Object.entries(update.constraintTable)) {
164
+ const obj = this.uuid == uuid ? this.self : this.teams[uuid];
165
+ obj[utils_1.Unpack](table);
166
+ }
167
+ }
168
+ parseEdit(update) {
169
+ let route = update.team ? this.teams : this.clients;
170
+ if (!route)
171
+ return;
172
+ // Loop through path to get to object being edited
173
+ for (const p of update.path.slice(0, -1)) {
174
+ // Create new object at path if non-existent
175
+ if (!(p in route))
176
+ route[p] = new utils_1.EditWrapper({});
177
+ route = route[p];
178
+ }
179
+ const prop = update.path.slice(-1)[0];
180
+ route[prop] = new utils_1.EditWrapper(update.value);
181
+ }
182
+ parseSelf(update) {
183
+ if (update.prop == 'controller') {
184
+ this.controller.listening = new Set(update.data);
185
+ }
186
+ else if (update.prop == 'uuid') {
187
+ this.uuid = update.data;
188
+ }
189
+ else if (update.prop == 'constraint') {
190
+ let route = this.uuid == update.data.path[0] ? this.self : this.teams[update.data.path[0]];
191
+ for (const prop of update.data.path.slice(1))
192
+ route = route === null || route === void 0 ? void 0 : route[prop];
193
+ if (route === undefined)
194
+ return;
195
+ route[utils_1.Unpack]({ [update.data.name]: update.data.args });
196
+ }
197
+ }
198
+ /**
199
+ * Add function to listener queue
200
+ * @param fn Function to call once frame is complete
201
+ */
202
+ [utils_1.Add](fn) {
203
+ this.listenerQueue.push(fn);
204
+ }
205
+ }
206
+ Multyx.Start = Symbol('start');
207
+ Multyx.Connection = Symbol('connection');
208
+ Multyx.Disconnect = Symbol('disconnect');
209
+ Multyx.Edit = Symbol('edit');
210
+ Multyx.Native = Symbol('native');
211
+ Multyx.Custom = Symbol('custom');
212
+ Multyx.Any = Symbol('any');
213
+ exports.default = Multyx;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MultyxClientValue = exports.MultyxClientObject = exports.MultyxClientList = void 0;
4
+ const list_1 = require("./list");
5
+ exports.MultyxClientList = list_1.default;
6
+ const object_1 = require("./object");
7
+ exports.MultyxClientObject = object_1.default;
8
+ const value_1 = require("./value");
9
+ exports.MultyxClientValue = value_1.default;