@hcikn/colibri 1.0.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.
- package/README.md +117 -0
- package/dist/index.cjs +596 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +105 -0
- package/dist/index.d.ts +105 -0
- package/dist/index.js +507 -0
- package/dist/index.js.map +1 -0
- package/package.json +42 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
function _array_like_to_array(arr, len) {
|
|
3
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
4
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
5
|
+
return arr2;
|
|
6
|
+
}
|
|
7
|
+
function _array_without_holes(arr) {
|
|
8
|
+
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
9
|
+
}
|
|
10
|
+
function _class_call_check(instance, Constructor) {
|
|
11
|
+
if (!(instance instanceof Constructor)) {
|
|
12
|
+
throw new TypeError("Cannot call a class as a function");
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function _defineProperties(target, props) {
|
|
16
|
+
for(var i = 0; i < props.length; i++){
|
|
17
|
+
var descriptor = props[i];
|
|
18
|
+
descriptor.enumerable = descriptor.enumerable || false;
|
|
19
|
+
descriptor.configurable = true;
|
|
20
|
+
if ("value" in descriptor) descriptor.writable = true;
|
|
21
|
+
Object.defineProperty(target, descriptor.key, descriptor);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function _create_class(Constructor, protoProps, staticProps) {
|
|
25
|
+
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
|
26
|
+
if (staticProps) _defineProperties(Constructor, staticProps);
|
|
27
|
+
return Constructor;
|
|
28
|
+
}
|
|
29
|
+
function _instanceof(left, right) {
|
|
30
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
31
|
+
return !!right[Symbol.hasInstance](left);
|
|
32
|
+
} else {
|
|
33
|
+
return left instanceof right;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function _iterable_to_array(iter) {
|
|
37
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
38
|
+
}
|
|
39
|
+
function _non_iterable_spread() {
|
|
40
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
41
|
+
}
|
|
42
|
+
function _to_consumable_array(arr) {
|
|
43
|
+
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
44
|
+
}
|
|
45
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
46
|
+
if (!o) return;
|
|
47
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
48
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
49
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
50
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
51
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
52
|
+
}
|
|
53
|
+
var __create = Object.create;
|
|
54
|
+
var __defProp = Object.defineProperty;
|
|
55
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
56
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
57
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
58
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
59
|
+
var __export = function(target, all) {
|
|
60
|
+
for(var name in all)__defProp(target, name, {
|
|
61
|
+
get: all[name],
|
|
62
|
+
enumerable: true
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
var __copyProps = function(to, from, except, desc) {
|
|
66
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
67
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
68
|
+
try {
|
|
69
|
+
var _loop = function() {
|
|
70
|
+
var key = _step.value;
|
|
71
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
72
|
+
get: function() {
|
|
73
|
+
return from[key];
|
|
74
|
+
},
|
|
75
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
for(var _iterator = __getOwnPropNames(from)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true)_loop();
|
|
79
|
+
} catch (err) {
|
|
80
|
+
_didIteratorError = true;
|
|
81
|
+
_iteratorError = err;
|
|
82
|
+
} finally{
|
|
83
|
+
try {
|
|
84
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
85
|
+
_iterator.return();
|
|
86
|
+
}
|
|
87
|
+
} finally{
|
|
88
|
+
if (_didIteratorError) {
|
|
89
|
+
throw _iteratorError;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return to;
|
|
95
|
+
};
|
|
96
|
+
var __toESM = function(mod, isNodeMode, target) {
|
|
97
|
+
return target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(// If the importer is in node compatibility mode or this is not an ESM
|
|
98
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
99
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
100
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
101
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
102
|
+
value: mod,
|
|
103
|
+
enumerable: true
|
|
104
|
+
}) : target, mod);
|
|
105
|
+
};
|
|
106
|
+
var __toCommonJS = function(mod) {
|
|
107
|
+
return __copyProps(__defProp({}, "__esModule", {
|
|
108
|
+
value: true
|
|
109
|
+
}), mod);
|
|
110
|
+
};
|
|
111
|
+
// src/index.ts
|
|
112
|
+
var src_exports = {};
|
|
113
|
+
__export(src_exports, {
|
|
114
|
+
Colibri: function() {
|
|
115
|
+
return Colibri;
|
|
116
|
+
},
|
|
117
|
+
RegisterModelSync: function() {
|
|
118
|
+
return RegisterModelSync;
|
|
119
|
+
},
|
|
120
|
+
RemoteLogger: function() {
|
|
121
|
+
return RemoteLogger;
|
|
122
|
+
},
|
|
123
|
+
Sync: function() {
|
|
124
|
+
return Sync;
|
|
125
|
+
},
|
|
126
|
+
SyncModel: function() {
|
|
127
|
+
return SyncModel;
|
|
128
|
+
},
|
|
129
|
+
Synced: function() {
|
|
130
|
+
return Synced;
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
module.exports = __toCommonJS(src_exports);
|
|
134
|
+
// src/Networking.ts
|
|
135
|
+
var import_rxjs = require("rxjs");
|
|
136
|
+
var io = __toESM(require("socket.io-client"), 1);
|
|
137
|
+
var messageSubject = new import_rxjs.Subject();
|
|
138
|
+
var Messages = messageSubject.asObservable();
|
|
139
|
+
var location = "";
|
|
140
|
+
if (typeof window !== "undefined") {
|
|
141
|
+
location = window.location.hostname || "";
|
|
142
|
+
}
|
|
143
|
+
var socket;
|
|
144
|
+
var init = function(app, server) {
|
|
145
|
+
server !== null && server !== void 0 ? server : server = location;
|
|
146
|
+
if (!server.startsWith("http")) {
|
|
147
|
+
server = "http://" + server;
|
|
148
|
+
}
|
|
149
|
+
server += ":9011";
|
|
150
|
+
socket = io.connect(server, {
|
|
151
|
+
query: {
|
|
152
|
+
app: app,
|
|
153
|
+
version: "1"
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
console.debug("Connecting to ".concat(server));
|
|
157
|
+
socket.on("connect", function() {
|
|
158
|
+
console.debug("Connected to colibri server on ".concat(server));
|
|
159
|
+
});
|
|
160
|
+
socket.onAny(function(channel, msg) {
|
|
161
|
+
messageSubject.next({
|
|
162
|
+
channel: channel,
|
|
163
|
+
command: msg.command,
|
|
164
|
+
payload: msg.payload
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
};
|
|
168
|
+
var Colibri = {
|
|
169
|
+
init: init
|
|
170
|
+
};
|
|
171
|
+
var SendMessage = function(channel, command) {
|
|
172
|
+
var payload = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {};
|
|
173
|
+
socket.emit(channel, {
|
|
174
|
+
command: command,
|
|
175
|
+
payload: payload
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
var RegisterChannel = function(channel, handler) {
|
|
179
|
+
socket.on(channel, handler);
|
|
180
|
+
};
|
|
181
|
+
// src/Broadcasting.ts
|
|
182
|
+
var sendBool = function(channel, val) {
|
|
183
|
+
SendMessage(channel, "broadcast::bool", val);
|
|
184
|
+
};
|
|
185
|
+
var sendBoolArray = function(channel, val) {
|
|
186
|
+
SendMessage(channel, "broadcast::bool[]", val);
|
|
187
|
+
};
|
|
188
|
+
var sendNumber = function(channel, val) {
|
|
189
|
+
SendMessage(channel, "broadcast::float", val);
|
|
190
|
+
};
|
|
191
|
+
var sendNumberArray = function(channel, val) {
|
|
192
|
+
SendMessage(channel, "broadcast::float[]", val);
|
|
193
|
+
};
|
|
194
|
+
var sendString = function(channel, val) {
|
|
195
|
+
SendMessage(channel, "broadcast::string", val);
|
|
196
|
+
};
|
|
197
|
+
var sendStringArray = function(channel, val) {
|
|
198
|
+
SendMessage(channel, "broadcast::string[]", val);
|
|
199
|
+
};
|
|
200
|
+
var sendVector3 = function(channel, val) {
|
|
201
|
+
SendMessage(channel, "broadcast::vector3", val);
|
|
202
|
+
};
|
|
203
|
+
var sendVector3Array = function(channel, val) {
|
|
204
|
+
SendMessage(channel, "broadcast::vector3[]", val);
|
|
205
|
+
};
|
|
206
|
+
var sendQuaternion = function(channel, val) {
|
|
207
|
+
SendMessage(channel, "broadcast::quaternion", val);
|
|
208
|
+
};
|
|
209
|
+
var sendQuaternionArray = function(channel, val) {
|
|
210
|
+
SendMessage(channel, "broadcast::quaternion[]", val);
|
|
211
|
+
};
|
|
212
|
+
var sendColor = function(channel, val) {
|
|
213
|
+
SendMessage(channel, "broadcast::color", val);
|
|
214
|
+
};
|
|
215
|
+
var sendColorArray = function(channel, val) {
|
|
216
|
+
SendMessage(channel, "broadcast::color[]", val);
|
|
217
|
+
};
|
|
218
|
+
var sendJson = function(channel, val) {
|
|
219
|
+
SendMessage(channel, "broadcast::json", val);
|
|
220
|
+
};
|
|
221
|
+
var listeners = {};
|
|
222
|
+
var registerListener = function(channel, type, callback) {
|
|
223
|
+
if (listeners[channel] === void 0) {
|
|
224
|
+
listeners[channel] = {};
|
|
225
|
+
RegisterChannel(channel, function(msg) {
|
|
226
|
+
if (msg.command in listeners[channel]) {
|
|
227
|
+
listeners[channel][msg.command].forEach(function(cb) {
|
|
228
|
+
return cb(msg.payload);
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
if (listeners[channel][type] === void 0) {
|
|
234
|
+
listeners[channel][type] = [];
|
|
235
|
+
}
|
|
236
|
+
listeners[channel][type].push(callback);
|
|
237
|
+
};
|
|
238
|
+
var receiveBool = function(channel, callback) {
|
|
239
|
+
registerListener(channel, "broadcast::bool", callback);
|
|
240
|
+
};
|
|
241
|
+
var receiveBoolArray = function(channel, callback) {
|
|
242
|
+
registerListener(channel, "broadcast::bool[]", callback);
|
|
243
|
+
};
|
|
244
|
+
var receiveNumber = function(channel, callback) {
|
|
245
|
+
registerListener(channel, "broadcast::float", callback);
|
|
246
|
+
};
|
|
247
|
+
var receiveNumberArray = function(channel, callback) {
|
|
248
|
+
registerListener(channel, "broadcast::float[]", callback);
|
|
249
|
+
};
|
|
250
|
+
var receiveString = function(channel, callback) {
|
|
251
|
+
registerListener(channel, "broadcast::string", callback);
|
|
252
|
+
};
|
|
253
|
+
var receiveStringArray = function(channel, callback) {
|
|
254
|
+
registerListener(channel, "broadcast::string[]", callback);
|
|
255
|
+
};
|
|
256
|
+
var receiveVector3 = function(channel, callback) {
|
|
257
|
+
registerListener(channel, "broadcast::vector3", callback);
|
|
258
|
+
};
|
|
259
|
+
var receiveVector3Array = function(channel, callback) {
|
|
260
|
+
registerListener(channel, "broadcast::vector3[]", callback);
|
|
261
|
+
};
|
|
262
|
+
var receiveQuaternion = function(channel, callback) {
|
|
263
|
+
registerListener(channel, "broadcast::quaternion", callback);
|
|
264
|
+
};
|
|
265
|
+
var receiveQuaternionArray = function(channel, callback) {
|
|
266
|
+
registerListener(channel, "broadcast::quaternion[]", callback);
|
|
267
|
+
};
|
|
268
|
+
var receiveColor = function(channel, callback) {
|
|
269
|
+
registerListener(channel, "broadcast::color", callback);
|
|
270
|
+
};
|
|
271
|
+
var receiveColorArray = function(channel, callback) {
|
|
272
|
+
registerListener(channel, "broadcast::color[]", callback);
|
|
273
|
+
};
|
|
274
|
+
var receiveJson = function(channel, callback) {
|
|
275
|
+
registerListener(channel, "broadcast::json", callback);
|
|
276
|
+
};
|
|
277
|
+
var unregister = function(channel, callback) {
|
|
278
|
+
for(var command in listeners[channel]){
|
|
279
|
+
var index = listeners[channel][command].indexOf(callback);
|
|
280
|
+
if (index >= 0) {
|
|
281
|
+
listeners[channel][command].splice(index, 1);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
var Sync = {
|
|
286
|
+
sendBool: sendBool,
|
|
287
|
+
sendBoolArray: sendBoolArray,
|
|
288
|
+
sendNumber: sendNumber,
|
|
289
|
+
sendNumberArray: sendNumberArray,
|
|
290
|
+
sendString: sendString,
|
|
291
|
+
sendStringArray: sendStringArray,
|
|
292
|
+
sendVector3: sendVector3,
|
|
293
|
+
sendVector3Array: sendVector3Array,
|
|
294
|
+
sendQuaternion: sendQuaternion,
|
|
295
|
+
sendQuaternionArray: sendQuaternionArray,
|
|
296
|
+
sendColor: sendColor,
|
|
297
|
+
sendColorArray: sendColorArray,
|
|
298
|
+
sendJson: sendJson,
|
|
299
|
+
receiveBool: receiveBool,
|
|
300
|
+
receiveBoolArray: receiveBoolArray,
|
|
301
|
+
receiveNumber: receiveNumber,
|
|
302
|
+
receiveNumberArray: receiveNumberArray,
|
|
303
|
+
receiveString: receiveString,
|
|
304
|
+
receiveStringArray: receiveStringArray,
|
|
305
|
+
receiveVector3: receiveVector3,
|
|
306
|
+
receiveVector3Array: receiveVector3Array,
|
|
307
|
+
receiveQuaternion: receiveQuaternion,
|
|
308
|
+
receiveQuaternionArray: receiveQuaternionArray,
|
|
309
|
+
receiveColor: receiveColor,
|
|
310
|
+
receiveColorArray: receiveColorArray,
|
|
311
|
+
receiveJson: receiveJson,
|
|
312
|
+
unregister: unregister,
|
|
313
|
+
// for better compatibility with Unity Colibri
|
|
314
|
+
sendFloat: sendNumber,
|
|
315
|
+
sendInt: sendNumber,
|
|
316
|
+
sendFloatArray: sendNumberArray,
|
|
317
|
+
sendIntArray: sendNumberArray
|
|
318
|
+
};
|
|
319
|
+
// src/RemoteLogger.ts
|
|
320
|
+
var init2 = function() {
|
|
321
|
+
var consoleDebug = console.debug;
|
|
322
|
+
var consoleLog = console.log;
|
|
323
|
+
var consoleWarn = console.warn;
|
|
324
|
+
var consoleError = console.error;
|
|
325
|
+
var stringify = function(obj) {
|
|
326
|
+
if (_instanceof(obj, Error)) {
|
|
327
|
+
return obj.message + "\n" + obj.stack;
|
|
328
|
+
}
|
|
329
|
+
return JSON.stringify(obj);
|
|
330
|
+
};
|
|
331
|
+
console.debug = function init2() {
|
|
332
|
+
for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
|
|
333
|
+
args[_key] = arguments[_key];
|
|
334
|
+
}
|
|
335
|
+
consoleDebug.apply(this, Array.prototype.slice.call(args));
|
|
336
|
+
SendMessage("log", "debug", _to_consumable_array(args).map(stringify).join().trim());
|
|
337
|
+
};
|
|
338
|
+
console.log = function() {
|
|
339
|
+
for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
|
|
340
|
+
args[_key] = arguments[_key];
|
|
341
|
+
}
|
|
342
|
+
consoleLog.apply(this, Array.prototype.slice.call(args));
|
|
343
|
+
SendMessage("log", "info", _to_consumable_array(args).map(stringify).join().trim());
|
|
344
|
+
};
|
|
345
|
+
console.warn = function() {
|
|
346
|
+
for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
|
|
347
|
+
args[_key] = arguments[_key];
|
|
348
|
+
}
|
|
349
|
+
consoleWarn.apply(this, Array.prototype.slice.call(args));
|
|
350
|
+
SendMessage("log", "warning", _to_consumable_array(args).map(stringify).join().trim());
|
|
351
|
+
};
|
|
352
|
+
console.error = function() {
|
|
353
|
+
for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
|
|
354
|
+
args[_key] = arguments[_key];
|
|
355
|
+
}
|
|
356
|
+
consoleError.apply(this, Array.prototype.slice.call(args));
|
|
357
|
+
SendMessage("log", "error", _to_consumable_array(args).map(stringify).join().trim());
|
|
358
|
+
};
|
|
359
|
+
};
|
|
360
|
+
var RemoteLogger = {
|
|
361
|
+
init: init2
|
|
362
|
+
};
|
|
363
|
+
// src/ModelSynchronization.ts
|
|
364
|
+
var import_rxjs2 = require("rxjs");
|
|
365
|
+
var RegisterModelSync = function(registration) {
|
|
366
|
+
var name = registration.name || registration.type.name.toLowerCase();
|
|
367
|
+
SendMessage("".concat(name), "model::request");
|
|
368
|
+
console.log("Registering model '".concat(name, "'"));
|
|
369
|
+
RegisterChannel("".concat(name), function(payload) {
|
|
370
|
+
var msg = payload;
|
|
371
|
+
if (msg.command === "model::update") {
|
|
372
|
+
onUpdate(msg.payload);
|
|
373
|
+
} else if (msg.command === "model::delete") {
|
|
374
|
+
onDelete(msg.payload.id);
|
|
375
|
+
} else {
|
|
376
|
+
console.error("Unknown model command: ".concat(msg.command));
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
var models = new import_rxjs2.BehaviorSubject([]);
|
|
380
|
+
var onUpdate = function(modelData) {
|
|
381
|
+
var model = models.value.find(function(m) {
|
|
382
|
+
return m.id === modelData.id;
|
|
383
|
+
});
|
|
384
|
+
if (model) {
|
|
385
|
+
model.update(modelData);
|
|
386
|
+
models.next(_to_consumable_array(models.value));
|
|
387
|
+
} else if (modelData.id) {
|
|
388
|
+
var newModel = new registration.type(modelData.id);
|
|
389
|
+
newModel.modelChanges$.subscribe(function(changes) {
|
|
390
|
+
if (!newModel.ignoreNextChange) {
|
|
391
|
+
SendMessage("".concat(name), "model::update", newModel.toJson(changes));
|
|
392
|
+
}
|
|
393
|
+
newModel.ignoreNextChange = false;
|
|
394
|
+
models.next(_to_consumable_array(models.value));
|
|
395
|
+
});
|
|
396
|
+
newModel.update(modelData);
|
|
397
|
+
models.next(_to_consumable_array(models.value).concat([
|
|
398
|
+
newModel
|
|
399
|
+
]));
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
var onDelete = function(id) {
|
|
403
|
+
var model = models.value.find(function(m) {
|
|
404
|
+
return m.id === id;
|
|
405
|
+
});
|
|
406
|
+
model === null || model === void 0 ? void 0 : model.delete();
|
|
407
|
+
models.next(models.value.filter(function(m) {
|
|
408
|
+
return m.id !== id;
|
|
409
|
+
}));
|
|
410
|
+
};
|
|
411
|
+
var registerModel = function(model) {
|
|
412
|
+
model.modelChanges$.subscribe(function(changes) {
|
|
413
|
+
if (!model.ignoreNextChange) {
|
|
414
|
+
SendMessage("".concat(name), "model::update", model.toJson(changes));
|
|
415
|
+
}
|
|
416
|
+
model.ignoreNextChange = false;
|
|
417
|
+
});
|
|
418
|
+
SendMessage("".concat(name), "model::update", model.toJson());
|
|
419
|
+
models.next(_to_consumable_array(models.value).concat([
|
|
420
|
+
model
|
|
421
|
+
]));
|
|
422
|
+
};
|
|
423
|
+
return [
|
|
424
|
+
models.asObservable(),
|
|
425
|
+
registerModel
|
|
426
|
+
];
|
|
427
|
+
};
|
|
428
|
+
// src/SyncModel.ts
|
|
429
|
+
var import_rxjs3 = require("rxjs");
|
|
430
|
+
var SyncModel = /*#__PURE__*/ function() {
|
|
431
|
+
function SyncModel(id) {
|
|
432
|
+
var _this = this;
|
|
433
|
+
_class_call_check(this, SyncModel);
|
|
434
|
+
// TODO: move to ModelSynchronization or use a much better structure or something like that?
|
|
435
|
+
this.ignoreNextChange = false;
|
|
436
|
+
this.modelChanges = new import_rxjs3.Subject();
|
|
437
|
+
this.modelChanges$ = this.modelChanges.pipe((0, import_rxjs3.bufferTime)(1), (0, import_rxjs3.map)(function(changes) {
|
|
438
|
+
return changes.filter(_this.uniq);
|
|
439
|
+
}), (0, import_rxjs3.filter)(function(changes) {
|
|
440
|
+
return changes.length > 0;
|
|
441
|
+
}), (0, import_rxjs3.share)());
|
|
442
|
+
this.id = id;
|
|
443
|
+
}
|
|
444
|
+
_create_class(SyncModel, [
|
|
445
|
+
{
|
|
446
|
+
key: "uniq",
|
|
447
|
+
value: function uniq(value, index, array) {
|
|
448
|
+
return array.indexOf(value) === index;
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
key: "onModelChanges",
|
|
453
|
+
value: function onModelChanges(prop) {
|
|
454
|
+
this.modelChanges.next(prop);
|
|
455
|
+
}
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
key: "delete",
|
|
459
|
+
value: function _delete() {
|
|
460
|
+
this.modelChanges.complete();
|
|
461
|
+
}
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
key: "registerSyncedProperty",
|
|
465
|
+
value: function registerSyncedProperty(name, prop) {
|
|
466
|
+
if (!this.syncedProperties) {
|
|
467
|
+
this.syncedProperties = {};
|
|
468
|
+
}
|
|
469
|
+
this.syncedProperties[name] = prop;
|
|
470
|
+
}
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
key: "update",
|
|
474
|
+
value: function update(updates) {
|
|
475
|
+
var syncedProps = Object.getPrototypeOf(this).syncedProperties;
|
|
476
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
477
|
+
try {
|
|
478
|
+
for(var _iterator = Object.keys(updates)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
479
|
+
var key = _step.value;
|
|
480
|
+
if (key !== "id") {
|
|
481
|
+
var localKey = syncedProps[key];
|
|
482
|
+
if (localKey) {
|
|
483
|
+
this[localKey] = updates[key];
|
|
484
|
+
this.ignoreNextChange = true;
|
|
485
|
+
} else {
|
|
486
|
+
console.warn("Unknown property ".concat(key, " in ").concat(this.constructor.name));
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
} catch (err) {
|
|
491
|
+
_didIteratorError = true;
|
|
492
|
+
_iteratorError = err;
|
|
493
|
+
} finally{
|
|
494
|
+
try {
|
|
495
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
496
|
+
_iterator.return();
|
|
497
|
+
}
|
|
498
|
+
} finally{
|
|
499
|
+
if (_didIteratorError) {
|
|
500
|
+
throw _iteratorError;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
key: "toJson",
|
|
508
|
+
value: function toJson() {
|
|
509
|
+
var attributes = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : [];
|
|
510
|
+
var json = {
|
|
511
|
+
id: this.id
|
|
512
|
+
};
|
|
513
|
+
var syncedProps = Object.getPrototypeOf(this).syncedProperties;
|
|
514
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
515
|
+
try {
|
|
516
|
+
for(var _iterator = Object.keys(syncedProps)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
517
|
+
var key = _step.value;
|
|
518
|
+
var localKey = syncedProps[key];
|
|
519
|
+
if (attributes.length === 0 || attributes.includes(localKey)) {
|
|
520
|
+
json[key] = this[localKey];
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
} catch (err) {
|
|
524
|
+
_didIteratorError = true;
|
|
525
|
+
_iteratorError = err;
|
|
526
|
+
} finally{
|
|
527
|
+
try {
|
|
528
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
529
|
+
_iterator.return();
|
|
530
|
+
}
|
|
531
|
+
} finally{
|
|
532
|
+
if (_didIteratorError) {
|
|
533
|
+
throw _iteratorError;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
return json;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
]);
|
|
541
|
+
return SyncModel;
|
|
542
|
+
}();
|
|
543
|
+
// src/Synced.ts
|
|
544
|
+
var Synced = function() {
|
|
545
|
+
var syncedName = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : "";
|
|
546
|
+
return function Synced(target, key, descriptor) {
|
|
547
|
+
if (!syncedName) syncedName = key.toString();
|
|
548
|
+
syncedName = syncedName.toLowerCase();
|
|
549
|
+
if (!_instanceof(target, SyncModel)) {
|
|
550
|
+
console.error("Synced decorator can only be used on SyncModel properties");
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
var original = target[key];
|
|
554
|
+
target.registerSyncedProperty(syncedName, key);
|
|
555
|
+
if (!(descriptor === null || descriptor === void 0 ? void 0 : descriptor.get)) {
|
|
556
|
+
Reflect.deleteProperty(target, key);
|
|
557
|
+
Reflect.defineProperty(target, key, {
|
|
558
|
+
get: function() {
|
|
559
|
+
return original;
|
|
560
|
+
},
|
|
561
|
+
set: function(newVal) {
|
|
562
|
+
console.log("Set ".concat(key.toString(), " to ").concat(newVal));
|
|
563
|
+
original = newVal;
|
|
564
|
+
},
|
|
565
|
+
enumerable: true,
|
|
566
|
+
configurable: true
|
|
567
|
+
});
|
|
568
|
+
} else {
|
|
569
|
+
var originalAccessors = {
|
|
570
|
+
get: descriptor.get,
|
|
571
|
+
set: descriptor.set
|
|
572
|
+
};
|
|
573
|
+
descriptor.get = function() {
|
|
574
|
+
var ret = originalAccessors.get.call(this);
|
|
575
|
+
return ret;
|
|
576
|
+
};
|
|
577
|
+
descriptor.set = function(newval) {
|
|
578
|
+
var model = this;
|
|
579
|
+
model.modelChanges.next(String(key));
|
|
580
|
+
if (originalAccessors.set) {
|
|
581
|
+
originalAccessors.set.call(this, newval);
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
};
|
|
587
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
588
|
+
0 && (module.exports = {
|
|
589
|
+
Colibri: Colibri,
|
|
590
|
+
RegisterModelSync: RegisterModelSync,
|
|
591
|
+
RemoteLogger: RemoteLogger,
|
|
592
|
+
Sync: Sync,
|
|
593
|
+
SyncModel: SyncModel,
|
|
594
|
+
Synced: Synced
|
|
595
|
+
});
|
|
596
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/Networking.ts","../src/Broadcasting.ts","../src/RemoteLogger.ts","../src/ModelSynchronization.ts","../src/SyncModel.ts","../src/Synced.ts"],"names":["init","import_rxjs"],"mappings":"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","sourcesContent":["export { Colibri } from './Networking';\r\n\r\nexport * from './Broadcasting';\r\n\r\nexport * from './RemoteLogger';\r\n\r\nexport * from './ModelSynchronization';\r\nexport * from './Synced';\r\nexport * from './SyncModel';\r\n","import { Subject } from 'rxjs';\r\nimport * as io from 'socket.io-client';\r\n\r\nexport interface Message {\r\n channel: string,\r\n command: string,\r\n payload: unknown\r\n}\r\n\r\nconst messageSubject = new Subject<Message>();\r\nexport const Messages = messageSubject.asObservable();\r\n\r\nlet location = '';\r\nif (typeof window !== 'undefined') {\r\n location = window.location.hostname || '';\r\n}\r\nlet socket: io.Socket;\r\n\r\n\r\nconst init = (app: string, server?: string) => {\r\n server ??= location;\r\n\r\n if (!server.startsWith('http')) {\r\n server = 'http://' + server;\r\n }\r\n\r\n server += ':9011';\r\n\r\n socket = io.connect(server, { query: { app, version: '1' } });\r\n console.debug(`Connecting to ${server}`);\r\n socket.on('connect', () => {\r\n console.debug(`Connected to colibri server on ${server}`);\r\n });\r\n\r\n socket.onAny((channel, msg) => {\r\n // if (msg.command === 'rpcRequest') {\r\n // const result = CallRpc(msg.channel, msg.payload['parameters']);\r\n // socket.emit(msg.channel, {\r\n // group: APP_NAME,\r\n // command: 'rpcAnswer',\r\n // payload: {\r\n // result,\r\n // rpcId: msg.payload['rpcId']\r\n // }\r\n // });\r\n // }\r\n messageSubject.next({\r\n channel,\r\n command: msg.command,\r\n payload: msg.payload\r\n });\r\n });\r\n};\r\n\r\nexport const Colibri = {\r\n init\r\n};\r\n\r\n\r\n///////////////////////////\r\n/// Default communication\r\n///////////////////////////\r\nexport const SendMessage = (channel: string, command: string, payload: unknown = {}) => {\r\n socket.emit(channel, {\r\n command,\r\n payload\r\n });\r\n};\r\n\r\n\r\n///////////////////////////////////////////\r\n/// Handlers (e.g. model synchronization)\r\n///////////////////////////////////////////\r\n\r\nexport const RegisterChannel = (channel: string, handler: (payload: Message) => void) => {\r\n socket.on(channel, handler);\r\n};\r\n\r\nexport const UnregisterChannel = (channel: string, handler: (payload: Message) => void) => {\r\n socket.off(channel, handler);\r\n};\r\n\r\nexport const RegisterOnce = (channel: string, handler: (payload: Message) => void) => {\r\n socket.once(channel, handler);\r\n};\r\n\r\n\r\n//////////////////\r\n/// RPC\r\n//////////////////\r\n// type rpcMethod = (payload: unknown) => unknown;\r\n// const rpcMethods: {[method: string]: rpcMethod } = {};\r\n// export const RegisterRpc = (method: string, fn: rpcMethod): void => {\r\n// rpcMethods[method] = fn;\r\n// };\r\n\r\n// export const SendRpc = async (method: string, payload: any): Promise<any> => {\r\n// // TODO\r\n// return null;\r\n// };\r\n\r\n// const CallRpc = (method: string, payload: any): any => {\r\n// if (rpcMethods[method])\r\n// return rpcMethods[method](payload);\r\n// else {\r\n// console.error(`Unknown rpc method ${method}`);\r\n// return 'error';\r\n// }\r\n// };\r\n\r\n\r\n// for debugging\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n// (window as any).SendMessage = SendMessage;\r\n// messageSubject.subscribe(console.log);\r\n","import { RegisterChannel, SendMessage, UnregisterChannel } from './Networking';\r\n\r\nconst sendBool = (channel: string, val: boolean) => {\r\n SendMessage(channel, 'broadcast::bool', val);\r\n};\r\n\r\nconst sendBoolArray = (channel: string, val: boolean[]) => {\r\n SendMessage(channel, 'broadcast::bool[]', val);\r\n};\r\n\r\nconst sendNumber = (channel: string, val: number) => {\r\n SendMessage(channel, 'broadcast::float', val);\r\n};\r\n\r\nconst sendNumberArray = (channel: string, val: number[]) => {\r\n SendMessage(channel, 'broadcast::float[]', val);\r\n};\r\n\r\nconst sendString = (channel: string, val: string) => {\r\n SendMessage(channel, 'broadcast::string', val);\r\n};\r\n\r\nconst sendStringArray = (channel: string, val: string[]) => {\r\n SendMessage(channel, 'broadcast::string[]', val);\r\n};\r\n\r\nconst sendVector3 = (channel: string, val: [number, number, number]) => {\r\n SendMessage(channel, 'broadcast::vector3', val);\r\n};\r\n\r\nconst sendVector3Array = (channel: string, val: [number, number, number][]) => {\r\n SendMessage(channel, 'broadcast::vector3[]', val);\r\n};\r\n\r\nconst sendQuaternion = (channel: string, val: [number, number, number, number]) => {\r\n SendMessage(channel, 'broadcast::quaternion', val);\r\n};\r\n\r\nconst sendQuaternionArray = (channel: string, val: [number, number, number, number][]) => {\r\n SendMessage(channel, 'broadcast::quaternion[]', val);\r\n};\r\n\r\nconst sendColor = (channel: string, val: [number, number, number, number]) => {\r\n SendMessage(channel, 'broadcast::color', val);\r\n};\r\n\r\nconst sendColorArray = (channel: string, val: [number, number, number, number][]) => {\r\n SendMessage(channel, 'broadcast::color[]', val);\r\n};\r\n\r\nconst sendJson = (channel: string, val: { [key: string]: unknown }) => {\r\n SendMessage(channel, 'broadcast::json', val);\r\n};\r\n\r\n\r\ntype genericCallback = (val: any) => void;\r\nconst listeners: { [channel: string]: { [ command: string ]: genericCallback[] } } = { };\r\n\r\nconst registerListener = <T>(channel: string, type: string, callback: (val: T) => void) => {\r\n if (listeners[channel] === undefined) {\r\n listeners[channel] = { };\r\n RegisterChannel(channel, (msg) => {\r\n if (msg.command in listeners[channel]) {\r\n listeners[channel][msg.command].forEach(cb => cb(msg.payload as T));\r\n }\r\n });\r\n }\r\n\r\n if (listeners[channel][type] === undefined) {\r\n listeners[channel][type] = [];\r\n }\r\n\r\n listeners[channel][type].push(callback);\r\n};\r\n\r\nconst receiveBool = (channel: string, callback: (val: boolean) => void) => {\r\n registerListener<boolean>(channel, 'broadcast::bool', callback);\r\n};\r\n\r\nconst receiveBoolArray = (channel: string, callback: (val: boolean[]) => void) => {\r\n registerListener<boolean[]>(channel, 'broadcast::bool[]', callback);\r\n};\r\n\r\nconst receiveNumber = (channel: string, callback: (val: number) => void) => {\r\n registerListener<number>(channel, 'broadcast::float', callback);\r\n};\r\n\r\nconst receiveNumberArray = (channel: string, callback: (val: number[]) => void) => {\r\n registerListener<number[]>(channel, 'broadcast::float[]', callback);\r\n};\r\n\r\nconst receiveString = (channel: string, callback: (val: string) => void) => {\r\n registerListener<string>(channel, 'broadcast::string', callback);\r\n};\r\n\r\nconst receiveStringArray = (channel: string, callback: (val: string[]) => void) => {\r\n registerListener<string[]>(channel, 'broadcast::string[]', callback);\r\n};\r\n\r\nconst receiveVector3 = (channel: string, callback: (val: [number, number, number]) => void) => {\r\n registerListener<[number, number, number]>(channel, 'broadcast::vector3', callback);\r\n};\r\n\r\nconst receiveVector3Array = (channel: string, callback: (val: [number, number, number][]) => void) => {\r\n registerListener<[number, number, number][]>(channel, 'broadcast::vector3[]', callback);\r\n};\r\n\r\nconst receiveQuaternion = (channel: string, callback: (val: [number, number, number, number]) => void) => {\r\n registerListener<[number, number, number, number]>(channel, 'broadcast::quaternion', callback);\r\n};\r\n\r\nconst receiveQuaternionArray = (channel: string, callback: (val: [number, number, number, number][]) => void) => {\r\n registerListener<[number, number, number, number][]>(channel, 'broadcast::quaternion[]', callback);\r\n};\r\n\r\nconst receiveColor = (channel: string, callback: (val: string) => void) => {\r\n registerListener<string>(channel, 'broadcast::color', callback);\r\n};\r\n\r\nconst receiveColorArray = (channel: string, callback: (val: string[]) => void) => {\r\n registerListener<string[]>(channel, 'broadcast::color[]', callback);\r\n};\r\n\r\nconst receiveJson = (channel: string, callback: (val: { [key: string]: unknown }) => void) => {\r\n registerListener<any>(channel, 'broadcast::json', callback);\r\n};\r\n\r\n\r\nconst unregister = (channel: string, callback: genericCallback) => {\r\n for (const command in listeners[channel]) {\r\n const index = listeners[channel][command].indexOf(callback);\r\n if (index >= 0) {\r\n listeners[channel][command].splice(index, 1);\r\n }\r\n }\r\n\r\n // TODO: we should ideally unsubscribe from the channel if there are no more listeners\r\n};\r\n\r\nexport const Sync = {\r\n sendBool, sendBoolArray,\r\n sendNumber, sendNumberArray,\r\n sendString, sendStringArray,\r\n sendVector3, sendVector3Array,\r\n sendQuaternion, sendQuaternionArray,\r\n sendColor, sendColorArray,\r\n sendJson,\r\n\r\n receiveBool, receiveBoolArray,\r\n receiveNumber, receiveNumberArray,\r\n receiveString, receiveStringArray,\r\n receiveVector3, receiveVector3Array,\r\n receiveQuaternion, receiveQuaternionArray,\r\n receiveColor, receiveColorArray,\r\n receiveJson,\r\n\r\n unregister,\r\n\r\n // for better compatibility with Unity Colibri\r\n sendFloat: sendNumber,\r\n sendInt: sendNumber,\r\n sendFloatArray: sendNumberArray,\r\n sendIntArray: sendNumberArray,\r\n};\r\n","import { SendMessage } from './Networking';\r\n\r\nconst init = () => {\r\n // keep original console commands\r\n const consoleDebug = console.debug;\r\n const consoleLog = console.log;\r\n const consoleWarn = console.warn;\r\n const consoleError = console.error;\r\n\r\n const stringify = (obj: unknown): string => {\r\n if (obj instanceof Error) {\r\n return obj.message + '\\n' + obj.stack;\r\n }\r\n\r\n return JSON.stringify(obj);\r\n };\r\n\r\n // intercept calls from console\r\n console.debug = function(...args) {\r\n consoleDebug.apply(this, Array.prototype.slice.call(args));\r\n SendMessage('log', 'debug', [...args].map(stringify).join().trim());\r\n };\r\n console.log = function(...args) {\r\n consoleLog.apply(this, Array.prototype.slice.call(args));\r\n SendMessage('log', 'info', [...args].map(stringify).join().trim());\r\n };\r\n console.warn = function(...args) {\r\n consoleWarn.apply(this, Array.prototype.slice.call(args));\r\n SendMessage('log', 'warning', [...args].map(stringify).join().trim());\r\n };\r\n console.error = function(...args) {\r\n consoleError.apply(this, Array.prototype.slice.call(args));\r\n SendMessage('log', 'error', [...args].map(stringify).join().trim());\r\n };\r\n};\r\n\r\n\r\nexport const RemoteLogger = {\r\n init\r\n};\r\n","import { BehaviorSubject, Observable } from 'rxjs';\r\nimport { Message, RegisterChannel, SendMessage } from './Networking';\r\nimport { SyncModel } from './SyncModel';\r\n\r\ninterface ModelSyncMsg<T extends SyncModel<T>> extends Message {\r\n command: 'model::update' | 'model::delete';\r\n payload: Partial<T> & { id: string };\r\n}\r\n\r\ninterface ModelSyncRegistration<T> {\r\n name?: string;\r\n type: { new(id: string): T };\r\n}\r\n\r\ntype ModelSync<T> = [ Observable<T[]>, (model: T) => void ];\r\n\r\nexport const RegisterModelSync = <T extends SyncModel<T>>(registration: ModelSyncRegistration<T>): ModelSync<T> => {\r\n const name = registration.name || registration.type.name.toLowerCase();\r\n\r\n // initial data fetch\r\n SendMessage(`${name}`, 'model::request');\r\n\r\n // Register for updates\r\n console.log(`Registering model '${name}'`);\r\n RegisterChannel(`${name}`, (payload: Message) => {\r\n const msg = payload as ModelSyncMsg<T>;\r\n if (msg.command === 'model::update') {\r\n onUpdate(msg.payload);\r\n } else if (msg.command === 'model::delete') {\r\n onDelete(msg.payload.id);\r\n } else {\r\n console.error(`Unknown model command: ${msg.command}`);\r\n }\r\n });\r\n\r\n // Handle updates\r\n const models = new BehaviorSubject<T[]>([]);\r\n\r\n const onUpdate = (modelData: Partial<T>) => {\r\n const model = models.value.find(m => m.id === modelData.id);\r\n if (model) {\r\n // Update existing model\r\n model.update(modelData);\r\n models.next([...models.value]);\r\n } else if (modelData.id) {\r\n const newModel = new registration.type(modelData.id);\r\n\r\n newModel.modelChanges$.subscribe(changes => {\r\n // If we did the changes, we'll ignore it\r\n if (!newModel.ignoreNextChange) {\r\n SendMessage(`${name}`, 'model::update', newModel.toJson(changes));\r\n }\r\n newModel.ignoreNextChange = false;\r\n models.next([...models.value]);\r\n });\r\n\r\n newModel.update(modelData);\r\n models.next([...models.value, newModel]);\r\n }\r\n };\r\n\r\n const onDelete = (id: string) => {\r\n const model = models.value.find(m => m.id === id);\r\n model?.delete();\r\n models.next(models.value.filter(m => m.id !== id));\r\n };\r\n\r\n const registerModel = (model: T) => {\r\n model.modelChanges$.subscribe(changes => {\r\n // If we did the changes, we'll ignore it\r\n if (!model.ignoreNextChange) {\r\n SendMessage(`${name}`, 'model::update', model.toJson(changes));\r\n }\r\n model.ignoreNextChange = false;\r\n });\r\n\r\n // send initial model\r\n SendMessage(`${name}`, 'model::update', model.toJson());\r\n models.next([...models.value, model]);\r\n };\r\n\r\n return [ models.asObservable(), registerModel ];\r\n};\r\n\r\n","import { Subject, bufferTime, filter, map, share } from 'rxjs';\r\n\r\nexport abstract class SyncModel<T> {\r\n public readonly id: string;\r\n\r\n // FIXME: this is set in 'registerSyncedProperty' but the decorator is called after the constructor\r\n // FIXME: -> therefore only available via prototype!\r\n private syncedProperties!: { [key: string]: (string | symbol) };\r\n\r\n // TODO: move to ModelSynchronization or use a much better structure or something like that?\r\n public ignoreNextChange = false;\r\n\r\n public readonly modelChanges = new Subject<string>();\r\n public readonly modelChanges$ = this.modelChanges.pipe(\r\n bufferTime(1),\r\n map(changes => changes.filter(this.uniq)),\r\n filter(changes => changes.length > 0),\r\n share());\r\n\r\n public constructor(id: string) {\r\n this.id = id;\r\n }\r\n\r\n private uniq(value: string, index: number, array: string[]) {\r\n return array.indexOf(value) === index;\r\n }\r\n\r\n protected onModelChanges(prop: string): void {\r\n this.modelChanges.next(prop);\r\n }\r\n\r\n public delete(): void {\r\n this.modelChanges.complete();\r\n }\r\n\r\n public registerSyncedProperty(name: string, prop: string | symbol): void {\r\n // workaround since decorators are called before constructors\r\n if (!this.syncedProperties) {\r\n this.syncedProperties = {};\r\n }\r\n\r\n this.syncedProperties[name] = prop;\r\n }\r\n\r\n public update(updates: Partial<T>): void {\r\n const syncedProps = Object.getPrototypeOf(this).syncedProperties;\r\n\r\n for (const key of Object.keys(updates)) {\r\n if (key !== 'id') {\r\n const localKey = syncedProps[key];\r\n if (localKey) {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n (this as any)[localKey as keyof SyncModel<T>] = updates[key as keyof T];\r\n this.ignoreNextChange = true;\r\n } else {\r\n console.warn(`Unknown property ${key} in ${this.constructor.name}`);\r\n }\r\n }\r\n }\r\n }\r\n\r\n public toJson(attributes: string[] = []): Partial<T> {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const json: any = { id: this.id };\r\n\r\n // TODO: only changed properties\r\n const syncedProps = Object.getPrototypeOf(this).syncedProperties;\r\n for (const key of Object.keys(syncedProps)) {\r\n const localKey = syncedProps[key] as keyof SyncModel<T>;\r\n if (attributes.length === 0 || attributes.includes(localKey)) {\r\n json[key] = this[localKey];\r\n }\r\n }\r\n\r\n return json;\r\n }\r\n}","import { SyncModel } from './SyncModel';\r\n\r\n/**\r\n * This decorator can be attached to any property or accessor of a SyncModel. \r\n * It will cause the property to be synchronized with the server.\r\n * Refer to https://www.typescriptlang.org/docs/handbook/decorators.html\r\n */\r\nexport const Synced = <T>(syncedName: string = ''): PropertyDecorator => {\r\n\r\n return function (target: unknown, key: string | symbol, descriptor?: PropertyDescriptor): void {\r\n if (!syncedName)\r\n syncedName = key.toString();\r\n syncedName = syncedName.toLowerCase();\r\n\r\n if (!(target instanceof SyncModel)) {\r\n console.error('Synced decorator can only be used on SyncModel properties');\r\n return;\r\n }\r\n\r\n let original = target[key as keyof Object];\r\n // FIXME: this sets the property on the prototype, not the instance!\r\n target.registerSyncedProperty(syncedName, key);\r\n\r\n if (!descriptor?.get) {\r\n /**\r\n * TODO: This (i.e., for properties) doesn't work in react for some reason!\r\n */\r\n Reflect.deleteProperty(target, key);\r\n Reflect.defineProperty(target, key, {\r\n get: () => original,\r\n set: newVal => {\r\n console.log(`Set ${key.toString()} to ${newVal}`);\r\n original = newVal;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n } else {\r\n const originalAccessors = {\r\n get: descriptor.get,\r\n set: descriptor.set\r\n };\r\n\r\n descriptor.get = function (): T {\r\n const ret: T = originalAccessors.get.call(this);\r\n return ret;\r\n };\r\n\r\n descriptor.set = function (newval: T) {\r\n const model = this as SyncModel<T>;\r\n model.modelChanges.next(String(key));\r\n\r\n if (originalAccessors.set) {\r\n originalAccessors.set.call(this, newval);\r\n }\r\n };\r\n }\r\n };\r\n};\r\n"]}
|