multyx-client 0.1.0 → 0.1.2

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,116 @@
1
+ import { Update } from "./types";
2
+ export declare function UncompressUpdate(str: string): {
3
+ instruction: string;
4
+ team: boolean;
5
+ path: string[];
6
+ value: any;
7
+ property?: undefined;
8
+ data?: undefined;
9
+ name?: undefined;
10
+ response?: undefined;
11
+ uuid?: undefined;
12
+ publicData?: undefined;
13
+ clientUUID?: undefined;
14
+ client?: undefined;
15
+ tps?: undefined;
16
+ constraintTable?: undefined;
17
+ clients?: undefined;
18
+ teams?: undefined;
19
+ } | {
20
+ instruction: string;
21
+ property: string;
22
+ data: any;
23
+ team?: undefined;
24
+ path?: undefined;
25
+ value?: undefined;
26
+ name?: undefined;
27
+ response?: undefined;
28
+ uuid?: undefined;
29
+ publicData?: undefined;
30
+ clientUUID?: undefined;
31
+ client?: undefined;
32
+ tps?: undefined;
33
+ constraintTable?: undefined;
34
+ clients?: undefined;
35
+ teams?: undefined;
36
+ } | {
37
+ instruction: string;
38
+ name: string;
39
+ response: any;
40
+ team?: undefined;
41
+ path?: undefined;
42
+ value?: undefined;
43
+ property?: undefined;
44
+ data?: undefined;
45
+ uuid?: undefined;
46
+ publicData?: undefined;
47
+ clientUUID?: undefined;
48
+ client?: undefined;
49
+ tps?: undefined;
50
+ constraintTable?: undefined;
51
+ clients?: undefined;
52
+ teams?: undefined;
53
+ } | {
54
+ instruction: string;
55
+ uuid: string;
56
+ publicData: any;
57
+ team?: undefined;
58
+ path?: undefined;
59
+ value?: undefined;
60
+ property?: undefined;
61
+ data?: undefined;
62
+ name?: undefined;
63
+ response?: undefined;
64
+ clientUUID?: undefined;
65
+ client?: undefined;
66
+ tps?: undefined;
67
+ constraintTable?: undefined;
68
+ clients?: undefined;
69
+ teams?: undefined;
70
+ } | {
71
+ instruction: string;
72
+ clientUUID: string;
73
+ team?: undefined;
74
+ path?: undefined;
75
+ value?: undefined;
76
+ property?: undefined;
77
+ data?: undefined;
78
+ name?: undefined;
79
+ response?: undefined;
80
+ uuid?: undefined;
81
+ publicData?: undefined;
82
+ client?: undefined;
83
+ tps?: undefined;
84
+ constraintTable?: undefined;
85
+ clients?: undefined;
86
+ teams?: undefined;
87
+ } | {
88
+ instruction: string;
89
+ client: any;
90
+ tps: any;
91
+ constraintTable: any;
92
+ clients: any;
93
+ teams: any;
94
+ team?: undefined;
95
+ path?: undefined;
96
+ value?: undefined;
97
+ property?: undefined;
98
+ data?: undefined;
99
+ name?: undefined;
100
+ response?: undefined;
101
+ uuid?: undefined;
102
+ publicData?: undefined;
103
+ clientUUID?: undefined;
104
+ };
105
+ export declare function CompressUpdate(update: Update): string;
106
+ export declare class Message {
107
+ name: string;
108
+ data: any;
109
+ time: number;
110
+ native: boolean;
111
+ private constructor();
112
+ static BundleOperations(deltaTime: number, operations: Update[]): string;
113
+ static Native(update: Update): string;
114
+ static Parse(str: string): Message;
115
+ static Create(name: string, data: any): string;
116
+ }
package/dist/message.js CHANGED
@@ -1,6 +1,68 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Message = void 0;
4
+ exports.UncompressUpdate = UncompressUpdate;
5
+ exports.CompressUpdate = CompressUpdate;
6
+ function UncompressUpdate(str) {
7
+ const [target, ...escapedData] = str.split(/;,/);
8
+ const instruction = target[0];
9
+ const specifier = target.slice(1).replace(/;_/g, ';');
10
+ const data = escapedData.map(d => d.replace(/;_/g, ';')).map(d => d == "undefined" ? undefined : JSON.parse(d));
11
+ if (instruction == '0')
12
+ return { instruction: 'edit', team: false, path: specifier.split('.'), value: data[0] };
13
+ if (instruction == '1')
14
+ return { instruction: 'edit', team: true, path: specifier.split('.'), value: data[0] };
15
+ if (instruction == '2')
16
+ return { instruction: 'self', property: "controller", data: JSON.parse(specifier) };
17
+ if (instruction == '3')
18
+ return { instruction: 'self', property: "uuid", data: JSON.parse(specifier) };
19
+ if (instruction == '4')
20
+ return { instruction: 'self', property: "constraint", data: JSON.parse(specifier) };
21
+ if (instruction == '9')
22
+ return { instruction: 'self', property: "space", data: JSON.parse(specifier) };
23
+ if (instruction == '5')
24
+ return { instruction: 'resp', name: specifier, response: data[0] };
25
+ if (instruction == '6')
26
+ return { instruction: 'conn', uuid: specifier, publicData: data[0] };
27
+ if (instruction == '7')
28
+ return { instruction: 'dcon', clientUUID: specifier };
29
+ if (instruction == '8')
30
+ return {
31
+ instruction: 'init',
32
+ client: JSON.parse(specifier),
33
+ tps: data[0],
34
+ constraintTable: data[1],
35
+ clients: data[2],
36
+ teams: data[3]
37
+ };
38
+ }
39
+ function CompressUpdate(update) {
40
+ let code, pieces;
41
+ if (update.instruction == 'edit') {
42
+ code = 0;
43
+ pieces = [
44
+ update.path.join('.'),
45
+ JSON.stringify(update.value)
46
+ ];
47
+ }
48
+ else if (update.instruction == 'input') {
49
+ code = 1;
50
+ pieces = [update.input];
51
+ }
52
+ else if (update.instruction == 'resp') {
53
+ code = 2;
54
+ pieces = [update.name, JSON.stringify(update.response)];
55
+ }
56
+ if (!pieces)
57
+ return '';
58
+ let compressed = code;
59
+ for (let i = 0; i < pieces.length; i++) {
60
+ compressed += pieces[i].replace(/;/g, ';_');
61
+ if (i < pieces.length - 1)
62
+ compressed += ';,';
63
+ }
64
+ return JSON.stringify([compressed]);
65
+ }
4
66
  class Message {
5
67
  constructor(name, data, native = false) {
6
68
  this.name = name;
@@ -14,13 +76,15 @@ class Message {
14
76
  return JSON.stringify(new Message('_', { operations, deltaTime }));
15
77
  }
16
78
  static Native(update) {
17
- return JSON.stringify(new Message('_', update, true));
79
+ return CompressUpdate(update);
18
80
  }
19
81
  static Parse(str) {
82
+ var _a, _b;
20
83
  const parsed = JSON.parse(str);
21
- if (parsed.name[0] == '_')
22
- parsed.name = parsed.name.slice(1);
23
- return new Message(parsed.name, parsed.data, parsed.name == '');
84
+ if (Array.isArray(parsed)) {
85
+ return new Message('_', parsed, true);
86
+ }
87
+ return new Message((_a = parsed.name) !== null && _a !== void 0 ? _a : '', (_b = parsed.data) !== null && _b !== void 0 ? _b : '', false);
24
88
  }
25
89
  static Create(name, data) {
26
90
  if (name.length == 0)
@@ -0,0 +1,8 @@
1
+ export type Options = {
2
+ port?: number;
3
+ secure?: boolean;
4
+ uri?: string;
5
+ verbose?: boolean;
6
+ logUpdateFrame?: boolean;
7
+ };
8
+ export declare const DefaultOptions: Options;
package/dist/options.js CHANGED
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DefaultOptions = void 0;
4
4
  exports.DefaultOptions = {
5
- port: 443,
5
+ port: 8443,
6
6
  secure: false,
7
7
  uri: 'localhost',
8
8
  verbose: false,
@@ -0,0 +1,21 @@
1
+ export type RawObject<V = any> = {
2
+ [key: string | number | symbol]: V;
3
+ };
4
+ export type Value = string | number | boolean;
5
+ export type Constraint = (n: Value) => Value | null;
6
+ export type EditUpdate = {
7
+ instruction: 'edit';
8
+ path: string[];
9
+ value: any;
10
+ };
11
+ export type InputUpdate = {
12
+ instruction: 'input';
13
+ input: string;
14
+ data?: RawObject<Value>;
15
+ };
16
+ export type ResponseUpdate = {
17
+ instruction: 'resp';
18
+ name: string;
19
+ response: any;
20
+ };
21
+ export type Update = EditUpdate | InputUpdate | ResponseUpdate;
@@ -0,0 +1,29 @@
1
+ import { Constraint, RawObject, Value } from "./types";
2
+ export declare const Unpack: unique symbol;
3
+ export declare const Done: unique symbol;
4
+ export declare const Add: unique symbol;
5
+ export declare const Edit: unique symbol;
6
+ export declare class EditWrapper<T> {
7
+ value: T;
8
+ constructor(value: T);
9
+ }
10
+ /**
11
+ * Set a customized interpolation curve for values to follow
12
+ * @param values Slices to interpolate through. Time must be between 0 and 1, while progress is the percentage between the old value and new value at the respective time, where 0 represents old value and 1 represents new value
13
+ * @example
14
+ * ```js
15
+ * car.get('speed').interpolate([
16
+ * { time: 0, progress: 0 },
17
+ * { time: 0.2, progress: 0.6 },
18
+ * { time: 0.4, progress: 1.2 },
19
+ * { time: 0.6, progress: 1.4 },
20
+ * { time: 0.8, progress: 1.2 },
21
+ * { time: 1, progress: 1 }
22
+ * ]);
23
+ * ```
24
+ */
25
+ export declare function Interpolate(object: RawObject, property: string, interpolationCurve: {
26
+ time: number;
27
+ progress: number;
28
+ }[]): void;
29
+ export declare function BuildConstraint(name: string, args: Value[]): Constraint | void;
package/dist/utils.js CHANGED
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EditWrapper = exports.Add = exports.Done = exports.Unpack = void 0;
3
+ exports.EditWrapper = exports.Edit = exports.Add = exports.Done = exports.Unpack = void 0;
4
4
  exports.Interpolate = Interpolate;
5
5
  exports.BuildConstraint = BuildConstraint;
6
6
  exports.Unpack = Symbol("unpack");
7
7
  exports.Done = Symbol("done");
8
8
  exports.Add = Symbol("add");
9
+ exports.Edit = Symbol("edit");
9
10
  class EditWrapper {
10
11
  constructor(value) {
11
12
  this.value = value;
package/multyx.js CHANGED
@@ -1 +1 @@
1
- !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Multyx=e():t.Multyx=e()}(self,(()=>(()=>{"use strict";var t={376:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.Controller=void 0;const i=s(210);e.Controller=class{constructor(t){this.listening=new Set,this.ws=t,this.preventDefault=!1,this.keys={},this.mouse={x:NaN,y:NaN,down:!1,centerX:0,centerY:0,scaleX:1,scaleY:1},document.addEventListener("keydown",(t=>{this.preventDefault&&t.preventDefault;const e=t.key.toLowerCase();this.keys[e]&&this.listening.has("keyhold")&&this.relayInput("keyhold",{code:e}),this.keys[t.code]&&this.listening.has("keyhold")&&this.relayInput("keyhold",{code:t.code}),this.listening.has(e)&&!this.keys[e]&&this.relayInput("keydown",{code:t.key}),this.listening.has(t.code)&&!this.keys[t.code]&&this.relayInput("keydown",{code:t.code}),this.keys[e]=!0,this.keys[t.code]=!0})),document.addEventListener("keyup",(t=>{this.preventDefault&&t.preventDefault;const e=t.key.toLowerCase();delete this.keys[e],delete this.keys[t.code],this.listening.has(e)&&this.relayInput("keyup",{code:e}),this.listening.has(t.code)&&this.relayInput("keyup",{code:t.code})})),document.addEventListener("mousedown",(t=>{if(this.preventDefault&&t.preventDefault,this.mouseGetter){const t=this.mouseGetter();this.mouse.x=t.x,this.mouse.y=t.y}else this.mouse.x=(t.clientX-this.mouse.centerX)/this.mouse.scaleX,this.mouse.y=(t.clientY-this.mouse.centerY)/this.mouse.scaleY;this.mouse.down=!0,this.listening.has("mousedown")&&this.relayInput("mousedown",{x:this.mouse.x,y:this.mouse.y})})),document.addEventListener("mouseup",(t=>{if(this.preventDefault&&t.preventDefault,this.mouseGetter){const t=this.mouseGetter();this.mouse.x=t.x,this.mouse.y=t.y}else this.mouse.x=(t.clientX-this.mouse.centerX)/this.mouse.scaleX,this.mouse.y=(t.clientY-this.mouse.centerY)/this.mouse.scaleY;this.mouse.down=!1,this.listening.has("mouseup")&&this.relayInput("mouseup",{x:this.mouse.x,y:this.mouse.y})})),document.addEventListener("mousemove",(t=>{if(this.preventDefault&&t.preventDefault,this.mouseGetter){const t=this.mouseGetter();this.mouse.x=t.x,this.mouse.y=t.y}else this.mouse.x=(t.clientX-this.mouse.centerX)/this.mouse.scaleX,this.mouse.y=(t.clientY-this.mouse.centerY)/this.mouse.scaleY;this.listening.has("mousemove")&&this.relayInput("mousemove",{x:this.mouse.x,y:this.mouse.y})}))}mapCanvasPosition(t,e){var s,i,o,n,r,h,l,a,u,c,f,p,d,m,g,v;const b="top"in e,y="bottom"in e,w="left"in e,M="right"in e,x=e.anchor,j=t.getBoundingClientRect(),S=(t,...e)=>{const s=t?"Cannot include value for ":"Must include value for ",i=1==e.length?e[0]:e.slice(0,-1).join(", ")+(t?" and ":" or ")+e.slice(-1)[0],o=x?" if anchoring at "+x:" if not anchoring";console.error(s+i+o)},k=j.width/j.height,E=j.height/j.width;if((Number.isNaN(k)||Number.isNaN(E))&&console.error("Canvas element bounding box is flat, canvas must be present on the screen"),x){if("center"==x){if(b&&y&&e.top!==-e.bottom||w&&M&&e.left!==-e.right)return S(!0,"top","bottom","left","right");b?(e.left=w?e.left:M?-e.right:-Math.abs(k*e.top),e.right=w?-e.left:M?e.right:Math.abs(k*e.top),e.bottom=-e.top):y?(e.left=w?e.left:M?-e.right:-Math.abs(k*e.bottom),e.right=w?-e.left:M?e.right:Math.abs(k*e.bottom),e.top=-e.bottom):w?(e.top=b?e.top:y?-e.bottom:-Math.abs(E*e.left),e.bottom=b?-e.top:y?e.bottom:Math.abs(E*e.left),e.right=-e.left):M&&(e.top=b?e.top:y?-e.bottom:-Math.abs(E*e.right),e.bottom=b?-e.top:y?e.bottom:Math.abs(E*e.right),e.left=-e.right)}else if("bottom"==x){if(!w&&!M&&!b)return S(!1,"left","right","top");if(e.bottom)return S(!0,"bottom");e.bottom=0,w?(null!==(s=e.top)&&void 0!==s||(e.top=Math.abs(E*e.left*2)),null!==(i=e.right)&&void 0!==i||(e.right=-e.left)):M?(null!==(o=e.top)&&void 0!==o||(e.top=Math.abs(E*e.right*2)),null!==(n=e.left)&&void 0!==n||(e.left=-e.right)):(e.left=-Math.abs(k*e.top/2),e.right=-e.left)}else if("top"==x){if(!w&&!M&&!y)return S(!1,"left","right","bottom");if(e.top)return S(!0,"top");e.top=0,w?(null!==(r=e.bottom)&&void 0!==r||(e.bottom=Math.abs(E*e.left*2)),null!==(h=e.right)&&void 0!==h||(e.right=-e.left)):M?(null!==(l=e.bottom)&&void 0!==l||(e.bottom=Math.abs(E*e.right*2)),null!==(a=e.left)&&void 0!==a||(e.left=-e.right)):(e.left=-Math.abs(k*e.bottom/2),e.right=-e.left)}else if("left"==x){if(!b&&!y&&!M)return S(!1,"top","bottom","right");if(w)return S(!0,"left");e.left=0,b?(null!==(u=e.right)&&void 0!==u||(e.right=-Math.abs(k*e.top*2)),null!==(c=e.bottom)&&void 0!==c||(e.bottom=-e.top)):y?(null!==(f=e.right)&&void 0!==f||(e.right=Math.abs(k*e.bottom*2)),null!==(p=e.top)&&void 0!==p||(e.top=-e.bottom)):(e.top=-Math.abs(E*e.right/2),e.bottom=-e.top)}else if("right"==x){if(!b&&!y&&!w)return S(!1,"top","bottom","left");if(M)return S(!0,"right");e.right=0,b?(null!==(d=e.left)&&void 0!==d||(e.left=-Math.abs(k*e.top*2)),null!==(m=e.bottom)&&void 0!==m||(e.bottom=-e.top)):y?(null!==(g=e.left)&&void 0!==g||(e.left=Math.abs(k*e.bottom*2)),null!==(v=e.top)&&void 0!==v||(e.top=-e.bottom)):(e.top=-Math.abs(E*e.right/2),e.bottom=-e.top)}else if("topleft"==x){if(!M&&!y)return S(!1,"right","bottom");if(w||b)return S(!0,"left","top");e.left=e.top=0,M?e.bottom=Math.abs(E*e.right):e.right=Math.abs(k*e.bottom)}else if("topright"==x){if(!w&&!y)return S(!1,"left","bottom");if(M||b)return S(!0,"right","top");e.right=e.top=0,w?e.bottom=Math.abs(E*e.left):e.left=Math.abs(k*e.bottom)}else if("bottomleft"==x){if(!M&&!b)return S(!1,"right","top");if(y||w)return S(!0,"bottom","left");e.left=e.bottom=0,M?e.top=Math.abs(E*e.right):e.right=Math.abs(k*e.top)}else if("bottomright"==x){if(!b&&!w)return S(!1,"top","left");if(M||y)return S(!0,"bottom","right");e.right=e.bottom=0,w?e.top=Math.abs(E*e.left):e.left=Math.abs(k*e.top)}}else{if(!b&&!y)return S(!1,"top","bottom");if(y?b||(e.top=e.bottom-t.height):e.bottom=e.top+t.height,!w&&!M)return S(!1,"left","right");M?w||(e.left=e.right-t.width):e.right=e.left+t.width}const O=t.getContext("2d");O.setTransform(1,0,0,1,0,0),t.width=Math.floor(Math.abs(e.right-e.left)),t.height=Math.floor(Math.abs(e.bottom-e.top)),e.right<e.left&&O.scale(-1,1),e.top>e.bottom&&O.scale(1,-1),O.translate(-e.left,-e.top)}mapMousePosition(t,e,s=document.body,i=1,o=i){const n=window.innerWidth/(s instanceof HTMLCanvasElement?s.width:s.clientWidth),r=window.innerHeight/(s instanceof HTMLCanvasElement?s.height:s.clientHeight),h=s.getBoundingClientRect();this.mouse.centerX=h.left+t*n,this.mouse.centerY=h.top+e*r,this.mouse.scaleX=i*n,this.mouse.scaleY=o*r}mapMouseToCanvas(t){const e=t.getContext("2d").getTransform(),s=t.getBoundingClientRect(),i=s.width/t.width,o=s.height/t.height;this.mouse.centerX=s.left+e.e*i,this.mouse.centerY=s.top+e.f*o,this.mouse.scaleX=i*e.a,this.mouse.scaleY=o*e.d}setMouseAs(t){this.mouseGetter=t}relayInput(t,e){if(1!==this.ws.readyState)throw new Error("Websocket connection is "+(2==this.ws.readyState?"closing":"closed"));this.ws.send(i.Message.Native(Object.assign({instruction:"input",input:t},e?{data:e}:{})))}}},34:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.MultyxClientValue=e.MultyxClientObject=e.MultyxClientList=void 0;const i=s(70);e.MultyxClientList=i.default;const o=s(614);e.MultyxClientObject=o.default;const n=s(501);e.MultyxClientValue=n.default},70:(t,e,s)=>{var i;Object.defineProperty(e,"__esModule",{value:!0});const o=s(787),n=s(614);class r extends n.default{get value(){const t=[];for(let e=0;e<this.length;e++)t[e]=this.get(e).value;return t}constructor(t,e,s=[],n){return super(t,{},s,n),this.toString=()=>this.value.toString(),this.valueOf=()=>this.value,this[i]=()=>this.value,this.length=0,this.push(...e instanceof o.EditWrapper?e.value.map((t=>new o.EditWrapper(t))):e),new Proxy(this,{has:(t,e)=>e in t||t.has(e),get:(t,e)=>e in t?t[e]:t.get(e),set:(t,e,s)=>e in t?(t[e]=s,!0):t.set(e,s),deleteProperty:(t,e)=>t.delete(e,!1)})}set(t,e){if("string"==typeof t&&(t=parseInt(t)),void 0===e)return this.delete(t,!1);if(e instanceof o.EditWrapper&&void 0===e.value)return this.delete(t,!0);const s=super.set(t,e);return s&&t>=this.length&&(this.length=t+1),s}delete(t,e=!1){"string"==typeof t&&(t=parseInt(t));const s=super.delete(t,e);return s&&(this.length=this.reduce(((t,e,s)=>void 0!==e?s+1:t),0)),s}forAll(t){for(let e=0;e<this.length;e++)t(this.get(e),e);super.forAll(((e,s)=>t(s,e)))}push(...t){for(const e of t)this.set(this.length,e);return this.length}pop(){if(0===this.length)return null;const t=this.get(this.length);return this.delete(this.length),t}unshift(...t){for(let e=this.length-1;e>=0;e--)e>=t.length?this.set(e,this.get(e-t.length)):this.set(e,t[e]);return this.length}shift(){if(0==this.length)return;this.length--;const t=this.get(0);for(let t=0;t<this.length;t++)this.set(t,this.get(t+1));return t}splice(t,e,...s){void 0===e&&(e=this.length-t);let i=s.length-e;if(i>0)for(let s=this.length-1;s>=t+e;s--)this.set(s+i,this.get(s));else if(i<0){for(let s=t+e;s<this.length;s++)this.set(s+i,this.get(s));const s=this.length;for(let t=s+i;t<s;t++)this.set(t,void 0)}for(let e=t;e<s.length;e++)this.set(e,s[e])}filter(t){const e=[];for(let s=0;s<this.length;s++)e.push(t(this.get(s),s,this));let s=0;for(let t=0;t<e.length;t++)e[t]&&s&&this.set(t-s,this.get(t)),e[t]||s--}map(t){for(let e=0;e<this.length;e++)this.set(e,t(this.get(e),e,this))}flat(){for(let t=0;t<this.length;t++){const e=this.get(t);if(e instanceof r)for(let s=0;s<e.length;s++)t++,this.set(t,e[s])}}reduce(t,e){for(let s=0;s<this.length;s++)e=t(e,this.get(s),s,this);return e}reduceRight(t,e){for(let s=this.length-1;s>=0;s--)e=t(e,this.get(s),s,this);return e}reverse(){let t=this.length-1;for(let e=0;e<t;e++){const s=this.get(e),i=this.get(t);this.set(e,i),this.set(t,s)}return this}forEach(t){for(let e=0;e<this.length;e++)t(this.get(e),e,this)}every(t){for(let e=0;e<this.length;e++)if(!t(this.get(e),e,this))return!1;return!0}some(t){for(let e=0;e<this.length;e++)if(t(this.get(e),e,this))return!0;return!1}find(t){for(let e=0;e<this.length;e++)if(t(this.get(e),e,this))return this.get(e)}findIndex(t){for(let e=0;e<this.length;e++)if(t(this.get(e),e,this))return e;return-1}deorder(){const t=[];for(const e in this.object)t.push(this.get(e));return t}deorderEntries(){const t=[];for(const e in this.object)t.push([parseInt(e),this.get(e)]);return t}entries(){const t=[];for(let e=0;e<this.length;e++)t.push([this.get(e),e]);return t}keys(){return Array(this.length).fill(0).map(((t,e)=>e))}[Symbol.iterator](){const t=[];for(let e=0;e<this.length;e++)t[e]=this.get(e);return t[Symbol.iterator]()}}i=Symbol.toPrimitive,e.default=r},614:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0});const i=s(210),o=s(787),n=s(735),r=s(501);class h{get value(){const t={};for(const e in this.object)t[e]=this.object[e];return t}constructor(t,e,s=[],i){this.object={},this.propertyPath=s,this.multyx=t,this.editable=i,this.setterListeners=[],e instanceof h&&(e=e.value);for(const t in e instanceof o.EditWrapper?e.value:e)this.set(t,e instanceof o.EditWrapper?new o.EditWrapper(e.value[t]):e[t]);if(this.constructor===h)return new Proxy(this,{has:(t,e)=>t.has(e),get:(t,e)=>e in t?t[e]:t.get(e),set:(t,e,s)=>e in t?(t[e]=s,!0):t.set(e,s),deleteProperty:(t,e)=>t.delete(e,!1)})}has(t){return t in this.object}get(t){return this.object[t]}set(t,e){if(void 0===e)return this.delete(t);if(this.object[t]instanceof r.default)return this.object[t].set(e);if(e instanceof o.EditWrapper&&void 0===e.value)return this.delete(t,!0);if(!(e instanceof o.EditWrapper||this.editable))return this.multyx.options.verbose&&console.error(`Attempting to set property that is not editable. Setting '${this.propertyPath.join(".")+"."+t}' to ${e}`),!1;this.object[t]=new((0,n.default)(e instanceof o.EditWrapper?e.value:e))(this.multyx,e,[...this.propertyPath,t],this.editable);for(const e of this.setterListeners)this.multyx[o.Add]((()=>{this.has(t)&&e(t,this.get(t))}));return e instanceof o.EditWrapper||this.multyx.ws.send(i.Message.Native({instruction:"edit",path:this.propertyPath,value:this.object[t].value})),!0}delete(t,e=!1){return this.editable||e?(delete this.object[t],e||this.multyx.ws.send(i.Message.Native({instruction:"edit",path:[...this.propertyPath,t],value:void 0})),!0):(this.multyx.options.verbose&&console.error(`Attempting to delete property that is not editable. Deleting '${this.propertyPath.join(".")+"."+t}'`),!1)}forAll(t){for(let e in this.object)t(e,this.get(e));this.setterListeners.push(t)}keys(){return Object.keys(this.object)}values(){return Object.values(this.object)}entries(){const t=[];for(let e in this.object)t.push([e,this.get(e)]);return t}[o.Unpack](t){for(const e in t)this.object[e][o.Unpack](t[e])}}e.default=h},735:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(t){return Array.isArray(t)?s(70).default:"object"==typeof t?s(614).default:s(501).default}},501:(t,e,s)=>{var i;Object.defineProperty(e,"__esModule",{value:!0});const o=s(210),n=s(787);class r{get value(){return this.interpolator?this.interpolator.get():this._value}set value(t){this._value=t,this.interpolator&&this.interpolator.set()}constructor(t,e,s=[],o){this.toString=()=>this.value.toString(),this.valueOf=()=>this.value,this[i]=()=>this.value,this.propertyPath=s,this.editable=o,this.multyx=t,this.constraints={},this.set(e)}set(t){if(t instanceof n.EditWrapper)return this.value=t.value,!0;if(!this.editable)return this.multyx.options.verbose&&console.error(`Attempting to set property that is not editable. Setting '${this.propertyPath.join(".")}' to ${t}`),!1;let e=t;for(const s in this.constraints)if(e=(0,this.constraints[s])(e),null===e)return this.multyx.options.verbose&&console.error(`Attempting to set property that failed on constraint. Setting '${this.propertyPath.join(".")}' to ${t}, stopped by constraint '${s}'`),!1;return this.value===e?(this.value=e,!0):(this.value=e,this.multyx.ws.send(o.Message.Native({instruction:"edit",path:this.propertyPath,value:e})),!0)}[n.Unpack](t){for(const[e,s]of Object.entries(t)){const t=(0,n.BuildConstraint)(e,s);t&&(this.constraints[e]=t)}}Lerp(){this.interpolator={history:[{value:this._value,time:Date.now()},{value:this._value,time:Date.now()}],get:()=>{const[t,e]=this.interpolator.history,s=Math.min(1,(Date.now()-t.time)/Math.min(250,t.time-e.time));return Number.isNaN(s)||"number"!=typeof t.value||"number"!=typeof e.value?t.value:t.value*s+e.value*(1-s)},set:()=>{this.interpolator.history.pop(),this.interpolator.history.unshift({value:this._value,time:Date.now()})}}}PredictiveLerp(){this.interpolator={history:[{value:this._value,time:Date.now()},{value:this._value,time:Date.now()},{value:this._value,time:Date.now()}],get:()=>{const[t,e,s]=this.interpolator.history,i=Math.min(1,(Date.now()-t.time)/(t.time-e.time));return Number.isNaN(i)||"number"!=typeof s.value||"number"!=typeof t.value||"number"!=typeof e.value||Math.abs((t.value-e.value)/(e.value-s.value)-1)>.2?t.value:t.value*(1+i)-e.value*i},set:()=>{this.interpolator.history.pop(),this.interpolator.history.unshift({value:this._value,time:Date.now()})}}}}i=Symbol.toPrimitive,e.default=r},210:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.Message=void 0;class s{constructor(t,e,s=!1){this.name=t,this.data=e,this.time=Date.now(),this.native=s}static BundleOperations(t,e){return Array.isArray(e)||(e=[e]),JSON.stringify(new s("_",{operations:e,deltaTime:t}))}static Native(t){return JSON.stringify(new s("_",t,!0))}static Parse(t){const e=JSON.parse(t);return"_"==e.name[0]&&(e.name=e.name.slice(1)),new s(e.name,e.data,""==e.name)}static Create(t,e){if(0==t.length)throw new Error("Multyx message cannot have empty name");if("_"==t[0]&&(t="_"+t),"function"==typeof e)throw new Error("Multyx data must be JSON storable");return JSON.stringify(new s(t,e))}}e.Message=s},944:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.DefaultOptions=void 0,e.DefaultOptions={port:443,secure:!1,uri:"localhost",verbose:!1,logUpdateFrame:!1}},787:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.EditWrapper=e.Add=e.Done=e.Unpack=void 0,e.Interpolate=function(t,e,s){let i={value:t[e],time:Date.now()},o={value:t[e],time:Date.now()};Object.defineProperty(t,e,{get:()=>{const t=o.time-i.time;let e=s[0],n=s[0];for(const i of s)t>i.time&&i.time>e.time&&(e=i),t<i.time&&i.time<n.time&&(n=i);const r=(t-e.time)/(n.time-e.time),h=e.progress+r*(n.progress-e.progress);return Number.isNaN(h)?i.value:o.value*h+i.value*(1-h)},set:t=>Date.now()-o.time<10?(o.value=t,!0):(i=Object.assign({},o),o={value:t,time:Date.now()},!0)})},e.BuildConstraint=function(t,e){return"min"==t?t=>t>=e[0]?t:e[0]:"max"==t?t=>t<=e[0]?t:e[0]:"int"==t?t=>Math.floor(t):"ban"==t?t=>e.includes(t)?null:t:"disabled"==t?t=>e[0]?null:t:t=>t},e.Unpack=Symbol("unpack"),e.Done=Symbol("done"),e.Add=Symbol("add"),e.EditWrapper=class{constructor(t){this.value=t}}}},e={};function s(i){var o=e[i];if(void 0!==o)return o.exports;var n=e[i]={exports:{}};return t[i](n,n.exports,s),n.exports}var i={};return(()=>{var t=i;const e=s(210),o=s(787),n=s(376),r=s(34),h=s(944);class l{constructor(t={},s){this.options=Object.assign(Object.assign({},h.DefaultOptions),t);const i=`ws${this.options.secure?"s":""}://${this.options.uri}:${this.options.port}/`;this.ws=new WebSocket(i),this.ping=0,this.events=new Map,this.self={},this.all={},this.teams={},this.clients={},this.controller=new n.Controller(this.ws),this.listenerQueue=[],null==s||s(),this.ws.onmessage=t=>{var s,i,o;const n=e.Message.Parse(t.data);this.ping=2*(Date.now()-n.time),n.native?(this.parseNativeEvent(n),null===(s=this.events.get(l.Native))||void 0===s||s.forEach((t=>t(n)))):n.name in this.events&&(this.events[n.name](n.data),null===(i=this.events.get(l.Custom))||void 0===i||i.forEach((t=>t(n)))),null===(o=this.events.get(l.Any))||void 0===o||o.forEach((t=>t(n)))}}on(t,e){var s;const i=null!==(s=this.events.get(t))&&void 0!==s?s:[];i.push(e),this.events.set(t,i)}send(t,s,i=!1){if("_"===t[0]&&(t="_"+t),this.ws.send(e.Message.Create(t,s)),i)return new Promise((e=>this.events.set(Symbol.for("_"+t),[e])))}loop(t,e){if(e)this.on(l.Start,(()=>setInterval(t,Math.round(1e3/e))));else{const e=()=>{t(),requestAnimationFrame(e)};this.on(l.Start,(()=>requestAnimationFrame(e)))}}forAll(t){this.on(l.Start,(()=>{this.teams.all.clients.forAll((e=>t(this.clients[e])))})),this.on(l.Connection,t)}parseNativeEvent(t){var e,s,i,o;this.options.logUpdateFrame&&console.log(t);for(const n of t.data)switch(n.instruction){case"init":this.initialize(n);for(const t of null!==(e=this.events.get(l.Start))&&void 0!==e?e:[])this.listenerQueue.push((()=>t(n)));this.events.has(l.Start)&&(this.events.get(l.Start).length=0);break;case"edit":this.parseEdit(n);for(const t of null!==(s=this.events.get(l.Edit))&&void 0!==s?s:[])this.listenerQueue.push((()=>t(n)));break;case"self":this.parseSelf(n);break;case"conn":this.clients[n.uuid]=new r.MultyxClientObject(this,n.data,[n.uuid],!1);for(const t of null!==(i=this.events.get(l.Connection))&&void 0!==i?i:[])this.listenerQueue.push((()=>t(this.clients[n.uuid])));break;case"dcon":for(const t of null!==(o=this.events.get(l.Disconnect))&&void 0!==o?o:[]){const e=this.clients[n.client].value;this.listenerQueue.push((()=>t(e)))}delete this.clients[n.client];break;case"resp":(0,this.events.get(Symbol.for("_"+n.name))[0])(n.response);break;default:this.options.verbose&&console.error("Server error: Unknown native Multyx instruction")}this.listenerQueue.forEach((t=>t())),this.listenerQueue.length=0}initialize(t){this.uuid=t.client.uuid,this.joinTime=t.client.joinTime,this.controller.listening=new Set(t.client.controller),this.teams=new r.MultyxClientObject(this,{},[],!0);for(const e of Object.keys(t.teams))this.teams[e]=new o.EditWrapper(t.teams[e]);this.all=this.teams.all,this.clients={};for(const[e,s]of Object.entries(t.clients))e!=this.uuid&&(this.clients[e]=new r.MultyxClientObject(this,new o.EditWrapper(s),[e],!1));const e=new r.MultyxClientObject(this,new o.EditWrapper(t.client.self),[this.uuid],!0);this.self=e,this.clients[this.uuid]=e;for(const[e,s]of Object.entries(t.constraintTable))(this.uuid==e?this.self:this.teams[e])[o.Unpack](s)}parseEdit(t){let e=t.team?this.teams:this.clients;if(e){for(const s of t.path.slice(0,-1))s in e||(e[s]=new o.EditWrapper({})),e=e[s];e[t.path.slice(-1)[0]]=new o.EditWrapper(t.value)}}parseSelf(t){if("controller"==t.prop)this.controller.listening=new Set(t.data);else if("uuid"==t.prop)this.uuid=t.data;else if("constraint"==t.prop){let e=this.uuid==t.data.path[0]?this.self:this.teams[t.data.path[0]];for(const s of t.data.path.slice(1))e=null==e?void 0:e[s];if(void 0===e)return;e[o.Unpack]({[t.data.name]:t.data.args})}}[o.Add](t){this.listenerQueue.push(t)}}l.Start=Symbol("start"),l.Connection=Symbol("connection"),l.Disconnect=Symbol("disconnect"),l.Edit=Symbol("edit"),l.Native=Symbol("native"),l.Custom=Symbol("custom"),l.Any=Symbol("any"),t.default=l})(),i.default})()));
1
+ !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Multyx=e():t.Multyx=e()}(self,(()=>(()=>{"use strict";var t={376:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.Controller=void 0;const i=s(210);e.Controller=class{constructor(t){this.listening=new Set,this.ws=t,this.preventDefault=!1,this.keys={},this.mouse={x:NaN,y:NaN,down:!1,centerX:0,centerY:0,scaleX:1,scaleY:1},document.addEventListener("keydown",(t=>{this.preventDefault&&t.preventDefault;const e=t.key.toLowerCase();this.keys[e]&&this.listening.has("keyhold")&&this.relayInput("keyhold",{code:e}),this.keys[t.code]&&this.listening.has("keyhold")&&this.relayInput("keyhold",{code:t.code}),this.listening.has(e)&&!this.keys[e]&&this.relayInput("keydown",{code:t.key}),this.listening.has(t.code)&&!this.keys[t.code]&&this.relayInput("keydown",{code:t.code}),this.keys[e]=!0,this.keys[t.code]=!0})),document.addEventListener("keyup",(t=>{this.preventDefault&&t.preventDefault;const e=t.key.toLowerCase();delete this.keys[e],delete this.keys[t.code],this.listening.has(e)&&this.relayInput("keyup",{code:e}),this.listening.has(t.code)&&this.relayInput("keyup",{code:t.code})})),document.addEventListener("mousedown",(t=>{if(this.preventDefault&&t.preventDefault,this.mouseGetter){const t=this.mouseGetter();this.mouse.x=t.x,this.mouse.y=t.y}else this.mouse.x=(t.clientX-this.mouse.centerX)/this.mouse.scaleX,this.mouse.y=(t.clientY-this.mouse.centerY)/this.mouse.scaleY;this.mouse.down=!0,this.listening.has("mousedown")&&this.relayInput("mousedown",{x:this.mouse.x,y:this.mouse.y})})),document.addEventListener("mouseup",(t=>{if(this.preventDefault&&t.preventDefault,this.mouseGetter){const t=this.mouseGetter();this.mouse.x=t.x,this.mouse.y=t.y}else this.mouse.x=(t.clientX-this.mouse.centerX)/this.mouse.scaleX,this.mouse.y=(t.clientY-this.mouse.centerY)/this.mouse.scaleY;this.mouse.down=!1,this.listening.has("mouseup")&&this.relayInput("mouseup",{x:this.mouse.x,y:this.mouse.y})})),document.addEventListener("mousemove",(t=>{if(this.preventDefault&&t.preventDefault,this.mouseGetter){const t=this.mouseGetter();this.mouse.x=t.x,this.mouse.y=t.y}else this.mouse.x=(t.clientX-this.mouse.centerX)/this.mouse.scaleX,this.mouse.y=(t.clientY-this.mouse.centerY)/this.mouse.scaleY;this.listening.has("mousemove")&&this.relayInput("mousemove",{x:this.mouse.x,y:this.mouse.y})}))}mapCanvasPosition(t,e){var s,i,o,n,r,l,h,a,u,c,p,d,f,m,g,y;const b="top"in e,v="bottom"in e,w="left"in e,x="right"in e,M=e.anchor,S=t.getBoundingClientRect(),j=(t,...e)=>{const s=t?"Cannot include value for ":"Must include value for ",i=1==e.length?e[0]:e.slice(0,-1).join(", ")+(t?" and ":" or ")+e.slice(-1)[0],o=M?" if anchoring at "+M:" if not anchoring";console.error(s+i+o)},k=S.width/S.height,E=S.height/S.width;if((Number.isNaN(k)||Number.isNaN(E))&&console.error("Canvas element bounding box is flat, canvas must be present on the screen"),M){if("center"==M){if(b&&v&&e.top!==-e.bottom||w&&x&&e.left!==-e.right)return j(!0,"top","bottom","left","right");b?(e.left=w?e.left:x?-e.right:-Math.abs(k*e.top),e.right=w?-e.left:x?e.right:Math.abs(k*e.top),e.bottom=-e.top):v?(e.left=w?e.left:x?-e.right:-Math.abs(k*e.bottom),e.right=w?-e.left:x?e.right:Math.abs(k*e.bottom),e.top=-e.bottom):w?(e.top=b?e.top:v?-e.bottom:-Math.abs(E*e.left),e.bottom=b?-e.top:v?e.bottom:Math.abs(E*e.left),e.right=-e.left):x&&(e.top=b?e.top:v?-e.bottom:-Math.abs(E*e.right),e.bottom=b?-e.top:v?e.bottom:Math.abs(E*e.right),e.left=-e.right)}else if("bottom"==M){if(!w&&!x&&!b)return j(!1,"left","right","top");if(e.bottom)return j(!0,"bottom");e.bottom=0,w?(null!==(s=e.top)&&void 0!==s||(e.top=Math.abs(E*e.left*2)),null!==(i=e.right)&&void 0!==i||(e.right=-e.left)):x?(null!==(o=e.top)&&void 0!==o||(e.top=Math.abs(E*e.right*2)),null!==(n=e.left)&&void 0!==n||(e.left=-e.right)):(e.left=-Math.abs(k*e.top/2),e.right=-e.left)}else if("top"==M){if(!w&&!x&&!v)return j(!1,"left","right","bottom");if(e.top)return j(!0,"top");e.top=0,w?(null!==(r=e.bottom)&&void 0!==r||(e.bottom=Math.abs(E*e.left*2)),null!==(l=e.right)&&void 0!==l||(e.right=-e.left)):x?(null!==(h=e.bottom)&&void 0!==h||(e.bottom=Math.abs(E*e.right*2)),null!==(a=e.left)&&void 0!==a||(e.left=-e.right)):(e.left=-Math.abs(k*e.bottom/2),e.right=-e.left)}else if("left"==M){if(!b&&!v&&!x)return j(!1,"top","bottom","right");if(w)return j(!0,"left");e.left=0,b?(null!==(u=e.right)&&void 0!==u||(e.right=-Math.abs(k*e.top*2)),null!==(c=e.bottom)&&void 0!==c||(e.bottom=-e.top)):v?(null!==(p=e.right)&&void 0!==p||(e.right=Math.abs(k*e.bottom*2)),null!==(d=e.top)&&void 0!==d||(e.top=-e.bottom)):(e.top=-Math.abs(E*e.right/2),e.bottom=-e.top)}else if("right"==M){if(!b&&!v&&!w)return j(!1,"top","bottom","left");if(x)return j(!0,"right");e.right=0,b?(null!==(f=e.left)&&void 0!==f||(e.left=-Math.abs(k*e.top*2)),null!==(m=e.bottom)&&void 0!==m||(e.bottom=-e.top)):v?(null!==(g=e.left)&&void 0!==g||(e.left=Math.abs(k*e.bottom*2)),null!==(y=e.top)&&void 0!==y||(e.top=-e.bottom)):(e.top=-Math.abs(E*e.right/2),e.bottom=-e.top)}else if("topleft"==M){if(!x&&!v)return j(!1,"right","bottom");if(w||b)return j(!0,"left","top");e.left=e.top=0,x?e.bottom=Math.abs(E*e.right):e.right=Math.abs(k*e.bottom)}else if("topright"==M){if(!w&&!v)return j(!1,"left","bottom");if(x||b)return j(!0,"right","top");e.right=e.top=0,w?e.bottom=Math.abs(E*e.left):e.left=Math.abs(k*e.bottom)}else if("bottomleft"==M){if(!x&&!b)return j(!1,"right","top");if(v||w)return j(!0,"bottom","left");e.left=e.bottom=0,x?e.top=Math.abs(E*e.right):e.right=Math.abs(k*e.top)}else if("bottomright"==M){if(!b&&!w)return j(!1,"top","left");if(x||v)return j(!0,"bottom","right");e.right=e.bottom=0,w?e.top=Math.abs(E*e.left):e.left=Math.abs(k*e.top)}}else{if(!b&&!v)return j(!1,"top","bottom");if(v?b||(e.top=e.bottom-t.height):e.bottom=e.top+t.height,!w&&!x)return j(!1,"left","right");x?w||(e.left=e.right-t.width):e.right=e.left+t.width}const C=t.getContext("2d");C.setTransform(1,0,0,1,0,0),t.width=Math.floor(Math.abs(e.right-e.left)),t.height=Math.floor(Math.abs(e.bottom-e.top)),e.right<e.left&&C.scale(-1,1),e.top>e.bottom&&C.scale(1,-1),C.translate(-e.left,-e.top)}mapMousePosition(t,e,s=document.body,i=1,o=i){const n=window.innerWidth/(s instanceof HTMLCanvasElement?s.width:s.clientWidth),r=window.innerHeight/(s instanceof HTMLCanvasElement?s.height:s.clientHeight),l=s.getBoundingClientRect();this.mouse.centerX=l.left+t*n,this.mouse.centerY=l.top+e*r,this.mouse.scaleX=i*n,this.mouse.scaleY=o*r}mapMouseToCanvas(t){const e=t.getContext("2d").getTransform(),s=t.getBoundingClientRect(),i=s.width/t.width,o=s.height/t.height;this.mouse.centerX=s.left+e.e*i,this.mouse.centerY=s.top+e.f*o,this.mouse.scaleX=i*e.a,this.mouse.scaleY=o*e.d}setMouseAs(t){this.mouseGetter=t}relayInput(t,e){if(1!==this.ws.readyState)throw new Error("Websocket connection is "+(2==this.ws.readyState?"closing":"closed"));this.ws.send(i.Message.Native(Object.assign({instruction:"input",input:t},e?{data:e}:{})))}}},34:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.MultyxClientValue=e.MultyxClientObject=e.MultyxClientList=void 0,e.IsMultyxClientItem=function(t){return t instanceof i.default||t instanceof o.default||t instanceof n.default};const i=s(70);e.MultyxClientList=i.default;const o=s(614);e.MultyxClientObject=o.default;const n=s(501);e.MultyxClientValue=n.default},70:(t,e,s)=>{var i;Object.defineProperty(e,"__esModule",{value:!0});const o=s(34),n=s(787),r=s(735),l=s(210);class h{addEditCallback(t){this.editCallbacks.push(t)}get value(){var t;const e=[];for(let s=0;s<this.length;s++)e[s]=null===(t=this.get(s))||void 0===t?void 0:t.value;return e}get length(){return this.list.length}set length(t){this.list.length=t}handleShiftOperation(t,e){const s=t>=0?e>=0?"right":"left":0==e?"reverse":e<0?"length":"unknown";switch(s){case"reverse":for(let t=0;t<Math.floor(this.length/2);t++){const e=this.list[t];this.list[t]=this.list[this.length-1-t],this.list[this.length-1-t]=e}break;case"left":for(let s=t;s<this.length;s++)s+e<0||(this.list[s+e]=this.list[s]);break;case"right":for(let s=this.length-1;s>=t;s--)this.list[s+e]=this.list[s];break;case"length":this.length+=e;break;default:this.multyx.options.verbose&&console.error("Unknown shift operation: "+s)}}constructor(t,e,s=[],o){this.editCallbacks=[],this.toString=()=>this.value.toString(),this.valueOf=()=>this.value,this[i]=()=>this.value,this.list=[],this.propertyPath=s,this.multyx=t,this.editable=o;const r=e instanceof n.EditWrapper;e instanceof h&&(e=e.value),e instanceof n.EditWrapper&&(e=e.value);for(let t=0;t<e.length;t++)this.set(t,r?new n.EditWrapper(e[t]):e[t]);return new Proxy(this,{has:(t,e)=>"number"==typeof e?t.has(e):e in t,get:(t,e)=>e in t?t[e]:(isNaN(parseInt(e))||(e=parseInt(e)),t.get(e)),set:(t,e,s)=>e in t?(t[e]=s,!0):!!t.set(e,s),deleteProperty:(t,e)=>"number"==typeof e&&t.delete(e)})}has(t){return t>=0&&t<this.length}get(t){if("number"==typeof t)return this.list[t];if(0==t.length)return this;if(1==t.length)return this.list[parseInt(t[0])];const e=this.list[parseInt(t[0])];return!e||e instanceof o.MultyxClientValue?void 0:e.get(t.slice(1))}recursiveSet(t,e){if(0==t.length)return this.multyx.options.verbose&&console.error(`Attempting to edit MultyxClientList with no path. Setting '${this.propertyPath.join(".")}' to ${e}`),!1;if("shift"==t[0]&&e instanceof n.EditWrapper)return this.handleShiftOperation(parseInt(t[1]),e.value),!0;if(1==t.length)return this.set(parseInt(t[0]),e);let s=this.get(parseInt(t[0]));return(s instanceof o.MultyxClientValue||null==s)&&(this.set(parseInt(t[0]),new n.EditWrapper({})),s=this.get(parseInt(t[0]))),s.set(t.slice(1),e)}set(t,e){if(Array.isArray(t))return this.recursiveSet(t,e);const s=this.get(t),i=e instanceof n.EditWrapper,l=i||this.editable;if((i||(0,o.IsMultyxClientItem)(e))&&(e=e.value),void 0===e)return this.delete(t,i);if(this.list[t]instanceof o.MultyxClientValue&&"object"!=typeof e)return this.list[t].set(i?new n.EditWrapper(e):e);if(!l)return this.multyx.options.verbose&&console.error(`Attempting to set property that is not editable. Setting '${this.propertyPath.join(".")+"."+t}' to ${e}`),!1;this.list[t]=new((0,r.default)(e))(this.multyx,i?new n.EditWrapper(e):e,[...this.propertyPath,t.toString()],this.editable);const h=Symbol.for("_"+this.propertyPath.join(".")+"."+t);this.multyx.events.has(h)&&this.multyx[n.Done].push(...this.multyx.events.get(h).map((e=>()=>e(this.list[t]))));for(const e of this.editCallbacks)this.multyx[n.Add]((()=>e(t,this.get(t),s)));return!0}delete(t,e=!1){const s=this.get(t);if("string"==typeof t&&(t=parseInt(t)),!this.editable&&!e)return this.multyx.options.verbose&&console.error(`Attempting to delete property that is not editable. Deleting '${this.propertyPath.join(".")+"."+t}'`),!1;delete this.list[t];for(const e of this.editCallbacks)this.multyx[n.Add]((()=>e(t,void 0,s)));return e||this.multyx.ws.send(l.Message.Native({instruction:"edit",path:[...this.propertyPath,t.toString()],value:void 0})),!0}await(t){if(this.has(t))return Promise.resolve(this.get(t));const e=Symbol.for("_"+this.propertyPath.join(".")+"."+t);return new Promise((t=>this.multyx.on(e,t)))}push(...t){for(const e of t)this.set(this.length,e);return this.length}pop(){if(0===this.length)return null;const t=this.get(this.length);return this.delete(this.length),t}unshift(...t){for(let e=this.length-1;e>=0;e--)e>=t.length?this.set(e,this.get(e-t.length)):this.set(e,t[e]);return this.length}shift(){if(0==this.length)return;this.length--;const t=this.get(0);for(let t=0;t<this.length;t++)this.set(t,this.get(t+1));return t}splice(t,e,...s){void 0===e&&(e=this.length-t);let i=s.length-e;if(i>0)for(let s=this.length-1;s>=t+e;s--)this.set(s+i,this.get(s));else if(i<0){for(let s=t+e;s<this.length;s++)this.set(s+i,this.get(s));const s=this.length;for(let t=s+i;t<s;t++)this.set(t,void 0)}for(let e=t;e<s.length;e++)this.set(e,s[e])}filter(t){const e=[];for(let s=0;s<this.length;s++)e.push(t(this.get(s),s,this));let s=0;for(let t=0;t<e.length;t++)e[t]&&s&&this.set(t-s,this.get(t)),e[t]||s--}map(t){const e=[];for(let s=0;s<this.length;s++)e.push(t(this.get(s),s,this))}flat(){for(let t=0;t<this.length;t++){const e=this.get(t);if(e instanceof h)for(let s=0;s<e.length;s++)t++,this.set(t,e[s])}}reduce(t,e){for(let s=0;s<this.length;s++)e=t(e,this.get(s),s,this);return e}reduceRight(t,e){for(let s=this.length-1;s>=0;s--)e=t(e,this.get(s),s,this);return e}reverse(){let t=this.length-1;for(let e=0;e<t;e++){const s=this.get(e),i=this.get(t);this.set(e,i),this.set(t,s)}return this}forEach(t){for(let e=0;e<this.length;e++)t(this.get(e),e,this)}every(t){for(let e=0;e<this.length;e++)if(!t(this.get(e),e,this))return!1;return!0}some(t){for(let e=0;e<this.length;e++)if(t(this.get(e),e,this))return!0;return!1}find(t){for(let e=0;e<this.length;e++)if(t(this.get(e),e,this))return this.get(e)}findIndex(t){for(let e=0;e<this.length;e++)if(t(this.get(e),e,this))return e;return-1}entries(){const t=[];for(let e=0;e<this.length;e++)t.push([this.get(e),e]);return t}keys(){return Array(this.length).fill(0).map(((t,e)=>e))}[n.Unpack](t){var e;for(let s=0;s<this.length;s++)null===(e=this.get(s))||void 0===e||e[n.Unpack](t[s])}[Symbol.iterator](){const t=[];for(let e=0;e<this.length;e++)t[e]=this.get(e);return t[Symbol.iterator]()}}i=Symbol.toPrimitive,e.default=h},614:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0});const i=s(210),o=s(787),n=s(34),r=s(735),l=s(501);class h{get value(){const t={};for(const e in this.object)t[e]=this.object[e];return t}addEditCallback(t){this.editCallbacks.push(t)}[o.Edit](t,e){1!=t.length?(0==t.length&&this.multyx.options.verbose&&console.error("Update path is empty. Attempting to edit MultyxClientObject with no path."),this.has(t[0])||this.set(t[0],new o.EditWrapper({})),this.get(t[0])[o.Edit](t.slice(1),e)):this.set(t[0],new o.EditWrapper(e))}constructor(t,e,s=[],i){this.editCallbacks=[],this.object={},this.propertyPath=s,this.multyx=t,this.editable=i;const n=e instanceof o.EditWrapper;e instanceof h&&(e=e.value),e instanceof o.EditWrapper&&(e=e.value);for(const t in e)this.set(t,n?new o.EditWrapper(e[t]):e[t]);if(this.constructor===h)return new Proxy(this,{has:(t,e)=>t.has(e),get:(t,e)=>e in t?t[e]:t.get(e),set:(t,e,s)=>e in t?(t[e]=s,!0):t.set(e,s),deleteProperty:(t,e)=>t.delete(e,!1)})}has(t){return t in this.object}get(t){if("string"==typeof t)return this.object[t];if(0==t.length)return this;if(1==t.length)return this.object[t[0]];const e=this.object[t[0]];return!e||e instanceof l.default?void 0:e.get(t.slice(1))}recursiveSet(t,e){if(0==t.length)return this.multyx.options.verbose&&console.error(`Attempting to edit MultyxClientObject with no path. Setting '${this.propertyPath.join(".")}' to ${e}`),!1;if(1==t.length)return this.set(t[0],e);let s=this.get(t[0]);return(s instanceof l.default||null==s)&&(isNaN(parseInt(t[1]))?(this.set(t[0],new o.EditWrapper({})),s=this.get(t[0])):(this.set(t[0],new o.EditWrapper([])),s=this.get(t[0]))),s.set(t.slice(1),e)}set(t,e){if(Array.isArray(t))return this.recursiveSet(t,e);const s=e instanceof o.EditWrapper,i=s||this.editable;if((s||(0,n.IsMultyxClientItem)(e))&&(e=e.value),void 0===e)return this.delete(t,s);if(this.object[t]instanceof l.default&&"object"!=typeof e)return this.object[t].set(s?new o.EditWrapper(e):e);if(!i)return this.multyx.options.verbose&&console.error(`Attempting to set property that is not editable. Setting '${this.propertyPath.join(".")+"."+t}' to ${e}`),!1;this.object[t]=new((0,r.default)(e))(this.multyx,s?new o.EditWrapper(e):e,[...this.propertyPath,t],this.editable);const h=Symbol.for("_"+this.propertyPath.join(".")+"."+t);return this.multyx.events.has(h)&&this.multyx[o.Done].push(...this.multyx.events.get(h).map((e=>()=>e(this.object[t])))),!0}delete(t,e=!1){return this.editable||e?(delete this.object[t],e||this.multyx.ws.send(i.Message.Native({instruction:"edit",path:[...this.propertyPath,t],value:void 0})),!0):(this.multyx.options.verbose&&console.error(`Attempting to delete property that is not editable. Deleting '${this.propertyPath.join(".")+"."+t}'`),!1)}keys(){return Object.keys(this.object)}values(){return Object.values(this.object)}entries(){const t=[];for(let e in this.object)t.push([e,this.get(e)]);return t}await(t){if(this.has(t))return Promise.resolve(this.get(t));const e=Symbol.for("_"+this.propertyPath.join(".")+"."+t);return new Promise((t=>this.multyx.on(e,t)))}[o.Unpack](t){var e;for(const s in t)null===(e=this.object[s])||void 0===e||e[o.Unpack](t[s])}}e.default=h},735:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(t){return Array.isArray(t)?s(70).default:"object"==typeof t?s(614).default:s(501).default}},501:(t,e,s)=>{var i;Object.defineProperty(e,"__esModule",{value:!0});const o=s(210),n=s(787);class r{get value(){return this.readModifiers.reduce(((t,e)=>e(t)),this._value)}set value(t){this._value=t}addReadModifier(t){this.readModifiers.push(t)}addEditCallback(t){this.editCallbacks.push(t)}[n.Edit](t,e){0==t.length&&this.set(new n.EditWrapper(e))}constructor(t,e,s=[],o){this.readModifiers=[],this.editCallbacks=[],this.toString=()=>this.value.toString(),this.valueOf=()=>this.value,this[i]=()=>this.value,this.propertyPath=s,this.editable=o,this.multyx=t,this.constraints={},this.set(e);const r=Symbol.for("_"+this.propertyPath.join("."));this.multyx.events.has(r)&&this.multyx[n.Done].push(...this.multyx.events.get(r).map((t=>()=>t(this.value))))}set(t){if(t instanceof n.EditWrapper){const e=this.value;return this.value=t.value,this.editCallbacks.forEach((s=>s(t.value,e))),!0}if(!this.editable)return this.multyx.options.verbose&&console.error(`Attempting to set property that is not editable. Setting '${this.propertyPath.join(".")}' to ${t}`),!1;let e=t;for(const s in this.constraints)if(e=(0,this.constraints[s])(e),null===e)return this.multyx.options.verbose&&console.error(`Attempting to set property that failed on constraint. Setting '${this.propertyPath.join(".")}' to ${t}, stopped by constraint '${s}'`),!1;return this.value===e?(this.value=e,!0):(this.value=e,this.multyx.ws.send(o.Message.Native({instruction:"edit",path:this.propertyPath,value:e})),!0)}bindElement(t){this.addEditCallback(((e,s)=>{e!==s&&(t.innerText=e.toString())}))}[n.Unpack](t){for(const[e,s]of Object.entries(t)){const t=(0,n.BuildConstraint)(e,s);t&&(this.constraints[e]=t)}}}i=Symbol.toPrimitive,e.default=r},210:(t,e)=>{function s(t){let e,s;if("edit"==t.instruction?(e=0,s=[t.path.join("."),JSON.stringify(t.value)]):"input"==t.instruction?(e=1,s=[t.input]):"resp"==t.instruction&&(e=2,s=[t.name,JSON.stringify(t.response)]),!s)return"";let i=e;for(let t=0;t<s.length;t++)i+=s[t].replace(/;/g,";_"),t<s.length-1&&(i+=";,");return JSON.stringify([i])}Object.defineProperty(e,"__esModule",{value:!0}),e.Message=void 0,e.UncompressUpdate=function(t){const[e,...s]=t.split(/;,/),i=e[0],o=e.slice(1).replace(/;_/g,";"),n=s.map((t=>t.replace(/;_/g,";"))).map((t=>"undefined"==t?void 0:JSON.parse(t)));return"0"==i?{instruction:"edit",team:!1,path:o.split("."),value:n[0]}:"1"==i?{instruction:"edit",team:!0,path:o.split("."),value:n[0]}:"2"==i?{instruction:"self",property:"controller",data:JSON.parse(o)}:"3"==i?{instruction:"self",property:"uuid",data:JSON.parse(o)}:"4"==i?{instruction:"self",property:"constraint",data:JSON.parse(o)}:"9"==i?{instruction:"self",property:"space",data:JSON.parse(o)}:"5"==i?{instruction:"resp",name:o,response:n[0]}:"6"==i?{instruction:"conn",uuid:o,publicData:n[0]}:"7"==i?{instruction:"dcon",clientUUID:o}:"8"==i?{instruction:"init",client:JSON.parse(o),tps:n[0],constraintTable:n[1],clients:n[2],teams:n[3]}:void 0},e.CompressUpdate=s;class i{constructor(t,e,s=!1){this.name=t,this.data=e,this.time=Date.now(),this.native=s}static BundleOperations(t,e){return Array.isArray(e)||(e=[e]),JSON.stringify(new i("_",{operations:e,deltaTime:t}))}static Native(t){return s(t)}static Parse(t){var e,s;const o=JSON.parse(t);return Array.isArray(o)?new i("_",o,!0):new i(null!==(e=o.name)&&void 0!==e?e:"",null!==(s=o.data)&&void 0!==s?s:"",!1)}static Create(t,e){if(0==t.length)throw new Error("Multyx message cannot have empty name");if("_"==t[0]&&(t="_"+t),"function"==typeof e)throw new Error("Multyx data must be JSON storable");return JSON.stringify(new i(t,e))}}e.Message=i},944:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.DefaultOptions=void 0,e.DefaultOptions={port:8443,secure:!1,uri:"localhost",verbose:!1,logUpdateFrame:!1}},787:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.EditWrapper=e.Edit=e.Add=e.Done=e.Unpack=void 0,e.Interpolate=function(t,e,s){let i={value:t[e],time:Date.now()},o={value:t[e],time:Date.now()};Object.defineProperty(t,e,{get:()=>{const t=o.time-i.time;let e=s[0],n=s[0];for(const i of s)t>i.time&&i.time>e.time&&(e=i),t<i.time&&i.time<n.time&&(n=i);const r=(t-e.time)/(n.time-e.time),l=e.progress+r*(n.progress-e.progress);return Number.isNaN(l)?i.value:o.value*l+i.value*(1-l)},set:t=>Date.now()-o.time<10?(o.value=t,!0):(i=Object.assign({},o),o={value:t,time:Date.now()},!0)})},e.BuildConstraint=function(t,e){return"min"==t?t=>t>=e[0]?t:e[0]:"max"==t?t=>t<=e[0]?t:e[0]:"int"==t?t=>Math.floor(t):"ban"==t?t=>e.includes(t)?null:t:"disabled"==t?t=>e[0]?null:t:t=>t},e.Unpack=Symbol("unpack"),e.Done=Symbol("done"),e.Add=Symbol("add"),e.Edit=Symbol("edit"),e.EditWrapper=class{constructor(t){this.value=t}}}},e={};function s(i){var o=e[i];if(void 0!==o)return o.exports;var n=e[i]={exports:{}};return t[i](n,n.exports,s),n.exports}var i={};return(()=>{var t,e=i;const o=s(210),n=s(787),r=s(376),l=s(34),h=s(944);class a{constructor(e={},s){var i;this[t]=[],this.options=Object.assign(Object.assign({},h.DefaultOptions),e);const n=`ws${this.options.secure?"s":""}://${this.options.uri.split("/")[0]}:${this.options.port}/${null!==(i=this.options.uri.split("/")[1])&&void 0!==i?i:""}`;this.ws=new WebSocket(n),this.ping=0,this.space="default",this.events=new Map,this.self={},this.tps=0,this.all={},this.teams=new l.MultyxClientObject(this,{},[],!0),this.clients={},this.controller=new r.Controller(this.ws),null==s||s(),this.ws.onmessage=t=>{var e,s,i,n;const r=o.Message.Parse(t.data);this.ping=2*(Date.now()-r.time),r.native?(this.parseNativeEvent(r),null===(e=this.events.get(a.Native))||void 0===e||e.forEach((t=>t(r)))):(null===(s=this.events.get(r.name))||void 0===s||s.forEach((t=>{const e=t(r.data);void 0!==e&&this.send(r.name,e)})),null===(i=this.events.get(a.Custom))||void 0===i||i.forEach((t=>t(r)))),null===(n=this.events.get(a.Any))||void 0===n||n.forEach((t=>t(r)))}}on(t,e){var s;const i=null!==(s=this.events.get(t))&&void 0!==s?s:[];i.push(e),this.events.set(t,i)}send(t,e){"_"===t[0]&&(t="_"+t);const s={instruction:"resp",name:t,response:e};this.ws.send(o.Message.Native(s))}await(t,e){return this.send(t,e),new Promise((e=>this.events.set(Symbol.for("_"+t),[e])))}loop(t,e){if(e)this.on(a.Start,(()=>setInterval(t,Math.round(1e3/e))));else{const e=()=>{t(),requestAnimationFrame(e)};this.on(a.Start,(()=>requestAnimationFrame(e)))}}[(t=n.Done,n.Add)](t){this[n.Done].push(t)}parseNativeEvent(t){var e,s,i,r;t.data=t.data.map(o.UncompressUpdate),this.options.logUpdateFrame&&console.log(t.data);for(const o of t.data)switch(o.instruction){case"init":this.initialize(o);for(const t of null!==(e=this.events.get(a.Start))&&void 0!==e?e:[])this[n.Done].push((()=>t(o)));this.events.has(a.Start)&&(this.events.get(a.Start).length=0);break;case"edit":if(1==o.path.length)o.team?this.teams.set(o.path[0],new n.EditWrapper(o.value)):this.clients[o.path[0]]=new l.MultyxClientObject(this,new n.EditWrapper(o.value),[o.path[0]],!1);else{const t=o.team?this.teams.get(o.path[0]):this.clients[o.path[0]];if(!t)return;t.set(o.path.slice(1),new n.EditWrapper(o.value))}for(const t of null!==(s=this.events.get(a.Edit))&&void 0!==s?s:[])this[n.Done].push((()=>t(o)));break;case"self":this.parseSelf(o);break;case"conn":this.clients[o.uuid]=new l.MultyxClientObject(this,o.data,[o.uuid],!1);for(const t of null!==(i=this.events.get(a.Connection))&&void 0!==i?i:[])this[n.Done].push((()=>t(this.clients[o.uuid])));break;case"dcon":for(const t of null!==(r=this.events.get(a.Disconnect))&&void 0!==r?r:[]){const e=this.clients[o.client].value;this[n.Done].push((()=>t(e)))}delete this.clients[o.client];break;case"resp":{const t=this.events.get(Symbol.for("_"+o.name))[0];this.events.delete(Symbol.for("_"+o.name)),this[n.Done].push((()=>t(o.response)));break}default:this.options.verbose&&console.error("Server error: Unknown native Multyx instruction")}this[n.Done].forEach((t=>t())),this[n.Done].length=0}initialize(t){this.tps=t.tps,this.uuid=t.client.uuid,this.joinTime=t.client.joinTime,this.controller.listening=new Set(t.client.controller);for(const e of Object.keys(t.teams))this.teams[e]=new n.EditWrapper(t.teams[e]);this.all=this.teams.all,this.clients={};for(const[e,s]of Object.entries(t.clients))e!=this.uuid&&(this.clients[e]=new l.MultyxClientObject(this,new n.EditWrapper(s),[e],!1));const e=new l.MultyxClientObject(this,new n.EditWrapper(t.client.self),[this.uuid],!0);this.self=e,this.clients[this.uuid]=e;for(const[e,s]of Object.entries(t.constraintTable))(this.uuid==e?this.self:this.teams[e])[n.Unpack](s)}parseSelf(t){if("controller"==t.property)this.controller.listening=new Set(t.data);else if("uuid"==t.property)this.uuid=t.data;else if("constraint"==t.property){let e=this.uuid==t.data.path[0]?this.self:this.teams[t.data.path[0]];for(const s of t.data.path.slice(1))e=null==e?void 0:e[s];if(void 0===e)return;e[n.Unpack]({[t.data.name]:t.data.args})}else"space"==t.property&&(this.space=t.data,this.updateSpace())}updateSpace(){"default"!=this.space?document.querySelectorAll("[data-multyx-space]").forEach((t=>{t.style.display=t.dataset.multyxSpace==this.space?"block":"none",t.style.pointerEvents=t.dataset.multyxSpace==this.space?"auto":"none"})):document.querySelectorAll("[data-multyx-space]").forEach((t=>{t.style.display="block",t.style.pointerEvents="auto"}))}}a.Start=Symbol("start"),a.Connection=Symbol("connection"),a.Disconnect=Symbol("disconnect"),a.Edit=Symbol("edit"),a.Native=Symbol("native"),a.Custom=Symbol("custom"),a.Any=Symbol("any"),e.default=a})(),i.default})()));
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "multyx-client",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Framework designed to simplify the creation of multiplayer browser games by addressing the complexities of managing server-client communication, shared state, and input handling",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
7
7
  "test": "echo \"Error: no test specified\" && exit 1",
8
- "build": "tsc",
9
- "webpack": "tsc && npx webpack"
8
+ "dev": "tsc",
9
+ "build": "tsc && npx webpack"
10
10
  },
11
11
  "repository": {
12
12
  "type": "git",