aes70 2.0.0 → 2.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/dist/AES70.es5.js +182 -160
- package/package.json +2 -2
- package/src/close_error.d.ts +4 -0
- package/src/close_error.js +13 -0
- package/src/connection.js +4 -3
- package/src/controller/base_event.js +6 -4
- package/src/controller/client_connection.js +4 -3
- package/src/controller/make_control_class.js +5 -0
- package/src/controller/notification_error.js +1 -1
- package/src/controller/observeProperty.js +1 -1
- package/src/controller/property_sync.js +18 -26
- package/src/index.default.d.ts +2 -0
- package/src/index.default.js +2 -0
- package/src/timeout_error.d.ts +3 -0
- package/src/timeout_error.js +9 -0
package/dist/AES70.es5.js
CHANGED
|
@@ -993,6 +993,16 @@
|
|
|
993
993
|
}
|
|
994
994
|
}
|
|
995
995
|
|
|
996
|
+
/**
|
|
997
|
+
* Error class raised when a connection is closed due to a timeout.
|
|
998
|
+
*/
|
|
999
|
+
class TimeoutError extends Error {
|
|
1000
|
+
constructor(error) {
|
|
1001
|
+
super(`Connection has timed out.`);
|
|
1002
|
+
this.name = 'aes70.TimeoutError';
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
|
|
996
1006
|
/**
|
|
997
1007
|
* Connection base class. It extends :class:`Events` and defines two events:
|
|
998
1008
|
*
|
|
@@ -1041,7 +1051,7 @@
|
|
|
1041
1051
|
if (this._closed) return;
|
|
1042
1052
|
this._closed = true;
|
|
1043
1053
|
this.emit('close');
|
|
1044
|
-
this.cleanup();
|
|
1054
|
+
this.cleanup(e);
|
|
1045
1055
|
});
|
|
1046
1056
|
}
|
|
1047
1057
|
|
|
@@ -1133,7 +1143,7 @@
|
|
|
1133
1143
|
this.emit('error', err);
|
|
1134
1144
|
}
|
|
1135
1145
|
|
|
1136
|
-
cleanup() {
|
|
1146
|
+
cleanup(error) {
|
|
1137
1147
|
if (this.is_closed()) throw new Error('cleanup() called twice.');
|
|
1138
1148
|
|
|
1139
1149
|
// disable keepalive
|
|
@@ -1150,7 +1160,7 @@
|
|
|
1150
1160
|
|
|
1151
1161
|
if (this.rx_idle_time() > t * 3) {
|
|
1152
1162
|
this.emit('timeout');
|
|
1153
|
-
this.error(new
|
|
1163
|
+
this.error(new TimeoutError());
|
|
1154
1164
|
} else if (this.tx_idle_time() > t * 0.75) {
|
|
1155
1165
|
/* Try to flush buffers before actually sending out anything. */
|
|
1156
1166
|
this.flush();
|
|
@@ -1527,6 +1537,20 @@
|
|
|
1527
1537
|
* @static
|
|
1528
1538
|
*/
|
|
1529
1539
|
|
|
1540
|
+
/**
|
|
1541
|
+
* Error class raised when a connection is closed.
|
|
1542
|
+
*
|
|
1543
|
+
* @property {Error} [error] - The actual failure reason. May be undefined,
|
|
1544
|
+
* for instance if the connection was closed using close().
|
|
1545
|
+
*/
|
|
1546
|
+
class CloseError extends Error {
|
|
1547
|
+
constructor(error) {
|
|
1548
|
+
super(`Connection has been closed.`);
|
|
1549
|
+
this.name = 'aes70.CloseError';
|
|
1550
|
+
this.error = error;
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1530
1554
|
class PendingCommand {
|
|
1531
1555
|
get handle() {
|
|
1532
1556
|
return this.command.handle;
|
|
@@ -1610,14 +1634,14 @@
|
|
|
1610
1634
|
this._subscribers = new Map();
|
|
1611
1635
|
}
|
|
1612
1636
|
|
|
1613
|
-
cleanup() {
|
|
1614
|
-
super.cleanup();
|
|
1637
|
+
cleanup(error) {
|
|
1638
|
+
super.cleanup(error);
|
|
1615
1639
|
const subscribers = this._subscribers;
|
|
1616
1640
|
this._subscribers = null;
|
|
1617
1641
|
const pendingCommands = this._pendingCommands;
|
|
1618
1642
|
this._pendingCommands = null;
|
|
1619
1643
|
|
|
1620
|
-
const e = new
|
|
1644
|
+
const e = new CloseError(error);
|
|
1621
1645
|
pendingCommands.forEach((pendingCommand, id) => {
|
|
1622
1646
|
pendingCommand.handleError(structuredClone(e));
|
|
1623
1647
|
});
|
|
@@ -2695,9 +2719,9 @@
|
|
|
2695
2719
|
const OcaResetCause = Enum8(OcaResetCause$1);
|
|
2696
2720
|
|
|
2697
2721
|
class EventSubscriber {
|
|
2698
|
-
constructor(callback,
|
|
2722
|
+
constructor(callback, failure_callback) {
|
|
2699
2723
|
this.callback = callback;
|
|
2700
|
-
this.failure_callback =
|
|
2724
|
+
this.failure_callback = failure_callback;
|
|
2701
2725
|
}
|
|
2702
2726
|
|
|
2703
2727
|
emit(ctx, results) {
|
|
@@ -2709,13 +2733,14 @@
|
|
|
2709
2733
|
}
|
|
2710
2734
|
|
|
2711
2735
|
emit_error(ctx, error) {
|
|
2712
|
-
if (this.
|
|
2736
|
+
if (this.failure_callback) {
|
|
2713
2737
|
try {
|
|
2714
|
-
this.
|
|
2738
|
+
this.failure_callback.call(ctx, error);
|
|
2715
2739
|
} catch (e) {
|
|
2716
2740
|
console.error('Exception thrown by error event handler: ', e);
|
|
2717
2741
|
}
|
|
2718
2742
|
} else {
|
|
2743
|
+
if (error instanceof CloseError) return;
|
|
2719
2744
|
console.warn('No handler for error', error);
|
|
2720
2745
|
}
|
|
2721
2746
|
}
|
|
@@ -2823,7 +2848,7 @@
|
|
|
2823
2848
|
[pos, try_again] = OcaBoolean.decodeFrom(view, pos);
|
|
2824
2849
|
[pos, data] = OcaBlob.decodeFrom(view, pos);
|
|
2825
2850
|
|
|
2826
|
-
return [type, try_again,
|
|
2851
|
+
return [type, try_again, data];
|
|
2827
2852
|
}
|
|
2828
2853
|
|
|
2829
2854
|
/**
|
|
@@ -3011,6 +3036,130 @@
|
|
|
3011
3036
|
* @static
|
|
3012
3037
|
*/
|
|
3013
3038
|
|
|
3039
|
+
/**
|
|
3040
|
+
* Observe a property in an object.
|
|
3041
|
+
*
|
|
3042
|
+
* The callback function is called when a property value or change is received. In
|
|
3043
|
+
* that case the callback is called with the arguments `true, value, changeIndex`. When an
|
|
3044
|
+
* error occurs, e.g. when fetching the initial property value using the corresponding
|
|
3045
|
+
* getter, the callback is called with arguments `false, Error`.
|
|
3046
|
+
*
|
|
3047
|
+
* The meaning of the changeIndex argument is meaningful in situations where a property has
|
|
3048
|
+
* associated min and max value. In that situation the value received by the callback is
|
|
3049
|
+
* the return value of the getter, which is an instance of Arguments. When either the property
|
|
3050
|
+
* itself or min/max changes, the changeIndex will be the corresponding index in the arguments
|
|
3051
|
+
* list. If the property has no min and max or when the initial value is returned from the
|
|
3052
|
+
* getter, the value of changeIndex is undefined.
|
|
3053
|
+
*
|
|
3054
|
+
* @param {ObjectBase} o The remote object.
|
|
3055
|
+
* @param {string|Property} property
|
|
3056
|
+
* @param {Function} callback The callback function
|
|
3057
|
+
* @returns An unsubscribe/cleanup function.
|
|
3058
|
+
*/
|
|
3059
|
+
function observeProperty(o, property, callback) {
|
|
3060
|
+
let propertyName;
|
|
3061
|
+
|
|
3062
|
+
if (typeof property === 'string') {
|
|
3063
|
+
propertyName = property;
|
|
3064
|
+
property = o.get_properties().find_property(propertyName);
|
|
3065
|
+
|
|
3066
|
+
if (!property)
|
|
3067
|
+
throw new Error(
|
|
3068
|
+
`Could not find property ${propertyName} in ${o.ClassName}`
|
|
3069
|
+
);
|
|
3070
|
+
} else {
|
|
3071
|
+
propertyName = property.name;
|
|
3072
|
+
}
|
|
3073
|
+
|
|
3074
|
+
if (property.static) {
|
|
3075
|
+
callback(true, o[propertyName]);
|
|
3076
|
+
return () => {};
|
|
3077
|
+
}
|
|
3078
|
+
|
|
3079
|
+
let lastValue = null;
|
|
3080
|
+
|
|
3081
|
+
const notify = (changeIndex) => {
|
|
3082
|
+
try {
|
|
3083
|
+
callback(true, lastValue, changeIndex);
|
|
3084
|
+
} catch (error) {
|
|
3085
|
+
console.error(
|
|
3086
|
+
'Subscriber',
|
|
3087
|
+
callback,
|
|
3088
|
+
'to property',
|
|
3089
|
+
propertyName,
|
|
3090
|
+
'in',
|
|
3091
|
+
o,
|
|
3092
|
+
'threw exception',
|
|
3093
|
+
error
|
|
3094
|
+
);
|
|
3095
|
+
}
|
|
3096
|
+
};
|
|
3097
|
+
|
|
3098
|
+
const eventCallback = (value, changeType, eventId) => {
|
|
3099
|
+
if (lastValue === null) return;
|
|
3100
|
+
switch (changeType.value) {
|
|
3101
|
+
case 1 /* OcaPropertyChangeType.CurrentChanged*/:
|
|
3102
|
+
if (lastValue instanceof Arguments) {
|
|
3103
|
+
lastValue.values[0] = value;
|
|
3104
|
+
notify(0);
|
|
3105
|
+
return;
|
|
3106
|
+
} else {
|
|
3107
|
+
lastValue = value;
|
|
3108
|
+
notify();
|
|
3109
|
+
return;
|
|
3110
|
+
}
|
|
3111
|
+
case 2 /*OcaPropertyChangeType.MinChanged*/:
|
|
3112
|
+
if (lastValue instanceof Arguments) {
|
|
3113
|
+
lastValue.values[1] = value;
|
|
3114
|
+
notify(1);
|
|
3115
|
+
return;
|
|
3116
|
+
}
|
|
3117
|
+
break;
|
|
3118
|
+
case 3 /*OcaPropertyChangeType.MaxChanged*/:
|
|
3119
|
+
if (lastValue instanceof Arguments) {
|
|
3120
|
+
lastValue.values[2] = value;
|
|
3121
|
+
notify(2);
|
|
3122
|
+
return;
|
|
3123
|
+
}
|
|
3124
|
+
break;
|
|
3125
|
+
}
|
|
3126
|
+
console.warn('Unhandled event', value, changeType, eventId);
|
|
3127
|
+
};
|
|
3128
|
+
|
|
3129
|
+
const errorCallback = (error) => {
|
|
3130
|
+
callback(false, error);
|
|
3131
|
+
};
|
|
3132
|
+
|
|
3133
|
+
let active = true;
|
|
3134
|
+
const event = property.event(o);
|
|
3135
|
+
const getter = property.getter(o);
|
|
3136
|
+
|
|
3137
|
+
if (!getter) {
|
|
3138
|
+
throw new Error(`No getter found for ${propertyName} in ${o.ClassName}`);
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3141
|
+
let unsubscribe = null;
|
|
3142
|
+
|
|
3143
|
+
if (event) {
|
|
3144
|
+
unsubscribe = event.subscribe(eventCallback, errorCallback);
|
|
3145
|
+
}
|
|
3146
|
+
|
|
3147
|
+
getter((ok, result) => {
|
|
3148
|
+
if (!active) return;
|
|
3149
|
+
if (!ok) {
|
|
3150
|
+
callback(false, result);
|
|
3151
|
+
} else {
|
|
3152
|
+
lastValue = result;
|
|
3153
|
+
notify();
|
|
3154
|
+
}
|
|
3155
|
+
});
|
|
3156
|
+
|
|
3157
|
+
return () => {
|
|
3158
|
+
active = false;
|
|
3159
|
+
if (unsubscribe) unsubscribe();
|
|
3160
|
+
};
|
|
3161
|
+
}
|
|
3162
|
+
|
|
3014
3163
|
/**
|
|
3015
3164
|
* Objects of this class can be used to keep a synchronized object containing
|
|
3016
3165
|
* all properties of a remote OCA object. Instances of this class are usually
|
|
@@ -3040,7 +3189,7 @@
|
|
|
3040
3189
|
sync() {
|
|
3041
3190
|
if (this.synchronized) return Promise.resolve();
|
|
3042
3191
|
|
|
3043
|
-
let
|
|
3192
|
+
let i = 0;
|
|
3044
3193
|
const tasks = [];
|
|
3045
3194
|
|
|
3046
3195
|
this.o.get_properties().forEach((prop) => {
|
|
@@ -3048,31 +3197,21 @@
|
|
|
3048
3197
|
|
|
3049
3198
|
if (!getter) return;
|
|
3050
3199
|
|
|
3051
|
-
const
|
|
3052
|
-
|
|
3053
|
-
const change_handler = function (index, value, changeType) {
|
|
3054
|
-
if (changeType !== OcaPropertyChangeType$1.CurrentChanged) return;
|
|
3055
|
-
|
|
3056
|
-
this.values[index] = value;
|
|
3057
|
-
};
|
|
3058
|
-
|
|
3059
|
-
const get_handler = function (index, value) {
|
|
3060
|
-
if (value instanceof Arguments) value = value.item(0);
|
|
3061
|
-
this.values[index] = value;
|
|
3062
|
-
};
|
|
3063
|
-
|
|
3064
|
-
if (event) {
|
|
3065
|
-
const cb = change_handler.bind(this, index);
|
|
3066
|
-
// NOTE: we do not want to wait for the promise to resolve
|
|
3067
|
-
// before storing this unsubscription handler because that
|
|
3068
|
-
// would have a potential race condition.
|
|
3069
|
-
this.subscriptions.push(event.unsubscribe.bind(event, cb));
|
|
3070
|
-
tasks.push(event.subscribe(cb).catch(function () {}));
|
|
3071
|
-
}
|
|
3072
|
-
|
|
3073
|
-
tasks.push(getter().then(get_handler.bind(this, index), function () {}));
|
|
3200
|
+
const index = i++;
|
|
3074
3201
|
|
|
3075
|
-
|
|
3202
|
+
const task = new Promise((resolve, reject) => {
|
|
3203
|
+
const unsubscribe = observeProperty(this.o, prop, (ok, result) => {
|
|
3204
|
+
if (ok) {
|
|
3205
|
+
this.values[index] =
|
|
3206
|
+
result instanceof Arguments ? result.item(0) : result;
|
|
3207
|
+
resolve();
|
|
3208
|
+
} else if (result instanceof RemoteError) {
|
|
3209
|
+
resolve();
|
|
3210
|
+
}
|
|
3211
|
+
});
|
|
3212
|
+
this.subscriptions.push(unsubscribe);
|
|
3213
|
+
});
|
|
3214
|
+
tasks.push(task);
|
|
3076
3215
|
});
|
|
3077
3216
|
|
|
3078
3217
|
return Promise.all(tasks);
|
|
@@ -3451,6 +3590,11 @@
|
|
|
3451
3590
|
if (has_setter) descriptor.set = make_setter(prop.setter(blue_print, true));
|
|
3452
3591
|
|
|
3453
3592
|
Object.defineProperty(o, prop.name, descriptor);
|
|
3593
|
+
if (prop.aliases) {
|
|
3594
|
+
prop.aliases.forEach((alias) => {
|
|
3595
|
+
Object.defineProperty(o, alias, descriptor);
|
|
3596
|
+
});
|
|
3597
|
+
}
|
|
3454
3598
|
index++;
|
|
3455
3599
|
});
|
|
3456
3600
|
|
|
@@ -23316,130 +23460,6 @@
|
|
|
23316
23460
|
}
|
|
23317
23461
|
}
|
|
23318
23462
|
|
|
23319
|
-
/**
|
|
23320
|
-
* Observe a property in an object.
|
|
23321
|
-
*
|
|
23322
|
-
* The callback function is called when a property value or change is received. In
|
|
23323
|
-
* that case the callback is called with the arguments `true, value, changeIndex`. When an
|
|
23324
|
-
* error occurs, e.g. when fetching the initial property value using the corresponding
|
|
23325
|
-
* getter, the callback is called with arguments `false, Error`.
|
|
23326
|
-
*
|
|
23327
|
-
* The meaning of the changeIndex argument is meaningful in situations where a property has
|
|
23328
|
-
* associated min and max value. In that situation the value received by the callback is
|
|
23329
|
-
* the return value of the getter, which is an instance of Arguments. When either the property
|
|
23330
|
-
* itself or min/max changes, the changeIndex will be the corresponding index in the arguments
|
|
23331
|
-
* list. If the property has no min and max or when the initial value is returned from the
|
|
23332
|
-
* getter, the value of changeIndex is undefined.
|
|
23333
|
-
*
|
|
23334
|
-
* @param {ObjectBase} o The remote object.
|
|
23335
|
-
* @param {string|Property} property
|
|
23336
|
-
* @param {Function} callback The callback function
|
|
23337
|
-
* @returns An unsubscribe/cleanup function.
|
|
23338
|
-
*/
|
|
23339
|
-
function observeProperty(o, property, callback) {
|
|
23340
|
-
let propertyName;
|
|
23341
|
-
|
|
23342
|
-
if (typeof property === 'string') {
|
|
23343
|
-
propertyName = property;
|
|
23344
|
-
property = o.get_properties().find_property(propertyName);
|
|
23345
|
-
|
|
23346
|
-
if (!property)
|
|
23347
|
-
throw new Error(
|
|
23348
|
-
`Could not find property ${propertyName} in ${o.ClassName}`
|
|
23349
|
-
);
|
|
23350
|
-
} else {
|
|
23351
|
-
propertyName = property.name;
|
|
23352
|
-
}
|
|
23353
|
-
|
|
23354
|
-
if (property.static) {
|
|
23355
|
-
callback(true, o[propertyName]);
|
|
23356
|
-
return () => {};
|
|
23357
|
-
}
|
|
23358
|
-
|
|
23359
|
-
let lastValue = null;
|
|
23360
|
-
|
|
23361
|
-
const notify = (changeIndex) => {
|
|
23362
|
-
try {
|
|
23363
|
-
callback(true, lastValue, changeIndex);
|
|
23364
|
-
} catch (error) {
|
|
23365
|
-
console.error(
|
|
23366
|
-
'Subscriber',
|
|
23367
|
-
callback,
|
|
23368
|
-
'to property',
|
|
23369
|
-
propertyName,
|
|
23370
|
-
'in',
|
|
23371
|
-
o,
|
|
23372
|
-
'threw exception',
|
|
23373
|
-
error
|
|
23374
|
-
);
|
|
23375
|
-
}
|
|
23376
|
-
};
|
|
23377
|
-
|
|
23378
|
-
const eventCallback = (value, changeType, eventId) => {
|
|
23379
|
-
if (lastValue === null) return;
|
|
23380
|
-
switch (changeType.value) {
|
|
23381
|
-
case 1 /* OcaPropertyChangeType.CurrentChanged*/:
|
|
23382
|
-
if (lastValue instanceof Arguments) {
|
|
23383
|
-
lastValue.values[0] = value;
|
|
23384
|
-
notify(0);
|
|
23385
|
-
return;
|
|
23386
|
-
} else {
|
|
23387
|
-
lastValue = value;
|
|
23388
|
-
notify();
|
|
23389
|
-
return;
|
|
23390
|
-
}
|
|
23391
|
-
case 2 /*OcaPropertyChangeType.MinChanged*/:
|
|
23392
|
-
if (lastValue instanceof Arguments) {
|
|
23393
|
-
lastValue.values[1] = value;
|
|
23394
|
-
notify(1);
|
|
23395
|
-
return;
|
|
23396
|
-
}
|
|
23397
|
-
break;
|
|
23398
|
-
case 3 /*OcaPropertyChangeType.MaxChanged*/:
|
|
23399
|
-
if (lastValue instanceof Arguments) {
|
|
23400
|
-
lastValue.values[2] = value;
|
|
23401
|
-
notify(2);
|
|
23402
|
-
return;
|
|
23403
|
-
}
|
|
23404
|
-
break;
|
|
23405
|
-
}
|
|
23406
|
-
console.warn('Unhandled event', value, changeType, eventId);
|
|
23407
|
-
};
|
|
23408
|
-
|
|
23409
|
-
const errorCallback = (error) => {
|
|
23410
|
-
callback(false, error);
|
|
23411
|
-
};
|
|
23412
|
-
|
|
23413
|
-
let active = true;
|
|
23414
|
-
const event = property.event(o);
|
|
23415
|
-
const getter = property.getter(o);
|
|
23416
|
-
|
|
23417
|
-
if (!getter) {
|
|
23418
|
-
throw new Error(`Not getter found for ${propertyName} in ${o.ClassName}`);
|
|
23419
|
-
}
|
|
23420
|
-
|
|
23421
|
-
let unsubscribe = null;
|
|
23422
|
-
|
|
23423
|
-
if (event) {
|
|
23424
|
-
unsubscribe = event.subscribe(eventCallback, errorCallback);
|
|
23425
|
-
}
|
|
23426
|
-
|
|
23427
|
-
getter((ok, result) => {
|
|
23428
|
-
if (!active) return;
|
|
23429
|
-
if (!ok) {
|
|
23430
|
-
callback(false, result);
|
|
23431
|
-
} else {
|
|
23432
|
-
lastValue = result;
|
|
23433
|
-
notify();
|
|
23434
|
-
}
|
|
23435
|
-
});
|
|
23436
|
-
|
|
23437
|
-
return () => {
|
|
23438
|
-
active = false;
|
|
23439
|
-
if (unsubscribe) unsubscribe();
|
|
23440
|
-
};
|
|
23441
|
-
}
|
|
23442
|
-
|
|
23443
23463
|
class PropertyObserver {
|
|
23444
23464
|
constructor(o, propertyName, cacheSubscriptions) {
|
|
23445
23465
|
this.o = o;
|
|
@@ -24488,6 +24508,7 @@
|
|
|
24488
24508
|
__proto__: null,
|
|
24489
24509
|
AbstractUDPConnection: AbstractUDPConnection,
|
|
24490
24510
|
ClientConnection: ClientConnection,
|
|
24511
|
+
CloseError: CloseError,
|
|
24491
24512
|
Command: Command,
|
|
24492
24513
|
CommandRrq: CommandRrq,
|
|
24493
24514
|
Connection: Connection,
|
|
@@ -24500,6 +24521,7 @@
|
|
|
24500
24521
|
RemoteDevice: RemoteDevice,
|
|
24501
24522
|
RemoteError: RemoteError,
|
|
24502
24523
|
Response: Response$1,
|
|
24524
|
+
TimeoutError: TimeoutError,
|
|
24503
24525
|
Types: types,
|
|
24504
24526
|
WebSocketConnection: WebSocketConnection,
|
|
24505
24527
|
currentProtocolVersion: currentProtocolVersion,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aes70",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "A controller library for the AES70 protocol.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"scripts": {
|
|
17
17
|
"test": "node --test --test-concurrency=1 tests/*.test.js",
|
|
18
18
|
"test:only": "node --test --test-only --test-concurrency=1 tests/*.test.js",
|
|
19
|
-
"prepublishOnly": "npx rollup@4.52.
|
|
19
|
+
"prepublishOnly": "npx rollup@4.52.4 src/bundle.browser.js --file dist/AES70.es5.js --format iife",
|
|
20
20
|
"docs": "cd esdoc && npm run build",
|
|
21
21
|
"prettier": "npx prettier@2.0.5 --write .",
|
|
22
22
|
"format": "npx prettier@2.0.5 --write .",
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error class raised when a connection is closed.
|
|
3
|
+
*
|
|
4
|
+
* @property {Error} [error] - The actual failure reason. May be undefined,
|
|
5
|
+
* for instance if the connection was closed using close().
|
|
6
|
+
*/
|
|
7
|
+
export class CloseError extends Error {
|
|
8
|
+
constructor(error) {
|
|
9
|
+
super(`Connection has been closed.`);
|
|
10
|
+
this.name = 'aes70.CloseError';
|
|
11
|
+
this.error = error;
|
|
12
|
+
}
|
|
13
|
+
}
|
package/src/connection.js
CHANGED
|
@@ -2,6 +2,7 @@ import { Events } from './events.js';
|
|
|
2
2
|
import { decodeMessage } from './OCP1/decode_message.js';
|
|
3
3
|
import { KeepAlive } from './OCP1/keepalive.js';
|
|
4
4
|
import { MessageGenerator } from './OCP1/message_generator.js';
|
|
5
|
+
import { TimeoutError } from './timeout_error.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Connection base class. It extends :class:`Events` and defines two events:
|
|
@@ -51,7 +52,7 @@ export class Connection extends Events {
|
|
|
51
52
|
if (this._closed) return;
|
|
52
53
|
this._closed = true;
|
|
53
54
|
this.emit('close');
|
|
54
|
-
this.cleanup();
|
|
55
|
+
this.cleanup(e);
|
|
55
56
|
});
|
|
56
57
|
}
|
|
57
58
|
|
|
@@ -143,7 +144,7 @@ export class Connection extends Events {
|
|
|
143
144
|
this.emit('error', err);
|
|
144
145
|
}
|
|
145
146
|
|
|
146
|
-
cleanup() {
|
|
147
|
+
cleanup(error) {
|
|
147
148
|
if (this.is_closed()) throw new Error('cleanup() called twice.');
|
|
148
149
|
|
|
149
150
|
// disable keepalive
|
|
@@ -160,7 +161,7 @@ export class Connection extends Events {
|
|
|
160
161
|
|
|
161
162
|
if (this.rx_idle_time() > t * 3) {
|
|
162
163
|
this.emit('timeout');
|
|
163
|
-
this.error(new
|
|
164
|
+
this.error(new TimeoutError());
|
|
164
165
|
} else if (this.tx_idle_time() > t * 0.75) {
|
|
165
166
|
/* Try to flush buffers before actually sending out anything. */
|
|
166
167
|
this.flush();
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { CloseError } from '../close_error.js';
|
|
1
2
|
import { OcaEvent } from '../types/OcaEvent.js';
|
|
2
3
|
|
|
3
4
|
class EventSubscriber {
|
|
4
|
-
constructor(callback,
|
|
5
|
+
constructor(callback, failure_callback) {
|
|
5
6
|
this.callback = callback;
|
|
6
|
-
this.failure_callback =
|
|
7
|
+
this.failure_callback = failure_callback;
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
emit(ctx, results) {
|
|
@@ -15,13 +16,14 @@ class EventSubscriber {
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
emit_error(ctx, error) {
|
|
18
|
-
if (this.
|
|
19
|
+
if (this.failure_callback) {
|
|
19
20
|
try {
|
|
20
|
-
this.
|
|
21
|
+
this.failure_callback.call(ctx, error);
|
|
21
22
|
} catch (e) {
|
|
22
23
|
console.error('Exception thrown by error event handler: ', e);
|
|
23
24
|
}
|
|
24
25
|
} else {
|
|
26
|
+
if (error instanceof CloseError) return;
|
|
25
27
|
console.warn('No handler for error', error);
|
|
26
28
|
}
|
|
27
29
|
}
|
|
@@ -8,6 +8,7 @@ import { Notification2 } from '../OCP1/notification2.js';
|
|
|
8
8
|
import { Arguments } from './arguments.js';
|
|
9
9
|
import { OcaStatus } from '../types/OcaStatus.js';
|
|
10
10
|
import { EncodedArguments } from '../OCP1/encoded_arguments.js';
|
|
11
|
+
import { CloseError } from '../close_error.js';
|
|
11
12
|
|
|
12
13
|
class PendingCommand {
|
|
13
14
|
get handle() {
|
|
@@ -92,14 +93,14 @@ export class ClientConnection extends Connection {
|
|
|
92
93
|
this._subscribers = new Map();
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
cleanup() {
|
|
96
|
-
super.cleanup();
|
|
96
|
+
cleanup(error) {
|
|
97
|
+
super.cleanup(error);
|
|
97
98
|
const subscribers = this._subscribers;
|
|
98
99
|
this._subscribers = null;
|
|
99
100
|
const pendingCommands = this._pendingCommands;
|
|
100
101
|
this._pendingCommands = null;
|
|
101
102
|
|
|
102
|
-
const e = new
|
|
103
|
+
const e = new CloseError(error);
|
|
103
104
|
pendingCommands.forEach((pendingCommand, id) => {
|
|
104
105
|
pendingCommand.handleError(structuredClone(e));
|
|
105
106
|
});
|
|
@@ -42,6 +42,11 @@ function createPropertySync(control_class) {
|
|
|
42
42
|
if (has_setter) descriptor.set = make_setter(prop.setter(blue_print, true));
|
|
43
43
|
|
|
44
44
|
Object.defineProperty(o, prop.name, descriptor);
|
|
45
|
+
if (prop.aliases) {
|
|
46
|
+
prop.aliases.forEach((alias) => {
|
|
47
|
+
Object.defineProperty(o, alias, descriptor);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
45
50
|
index++;
|
|
46
51
|
});
|
|
47
52
|
|
|
@@ -103,7 +103,7 @@ export function observeProperty(o, property, callback) {
|
|
|
103
103
|
const getter = property.getter(o);
|
|
104
104
|
|
|
105
105
|
if (!getter) {
|
|
106
|
-
throw new Error(`
|
|
106
|
+
throw new Error(`No getter found for ${propertyName} in ${o.ClassName}`);
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
let unsubscribe = null;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Arguments } from './arguments.js';
|
|
2
2
|
import { OcaPropertyChangeType } from '../types/OcaPropertyChangeType.js';
|
|
3
|
+
import { observeProperty } from './observeProperty.js';
|
|
4
|
+
import { RemoteError } from './remote_error.js';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Objects of this class can be used to keep a synchronized object containing
|
|
@@ -30,7 +32,7 @@ export class PropertySync {
|
|
|
30
32
|
sync() {
|
|
31
33
|
if (this.synchronized) return Promise.resolve();
|
|
32
34
|
|
|
33
|
-
let
|
|
35
|
+
let i = 0;
|
|
34
36
|
const tasks = [];
|
|
35
37
|
|
|
36
38
|
this.o.get_properties().forEach((prop) => {
|
|
@@ -38,31 +40,21 @@ export class PropertySync {
|
|
|
38
40
|
|
|
39
41
|
if (!getter) return;
|
|
40
42
|
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
// NOTE: we do not want to wait for the promise to resolve
|
|
57
|
-
// before storing this unsubscription handler because that
|
|
58
|
-
// would have a potential race condition.
|
|
59
|
-
this.subscriptions.push(event.unsubscribe.bind(event, cb));
|
|
60
|
-
tasks.push(event.subscribe(cb).catch(function () {}));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
tasks.push(getter().then(get_handler.bind(this, index), function () {}));
|
|
64
|
-
|
|
65
|
-
index++;
|
|
43
|
+
const index = i++;
|
|
44
|
+
|
|
45
|
+
const task = new Promise((resolve, reject) => {
|
|
46
|
+
const unsubscribe = observeProperty(this.o, prop, (ok, result) => {
|
|
47
|
+
if (ok) {
|
|
48
|
+
this.values[index] =
|
|
49
|
+
result instanceof Arguments ? result.item(0) : result;
|
|
50
|
+
resolve();
|
|
51
|
+
} else if (result instanceof RemoteError) {
|
|
52
|
+
resolve();
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
this.subscriptions.push(unsubscribe);
|
|
56
|
+
});
|
|
57
|
+
tasks.push(task);
|
|
66
58
|
});
|
|
67
59
|
|
|
68
60
|
return Promise.all(tasks);
|
package/src/index.default.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ export * from './controller/abstract_udp_connection';
|
|
|
16
16
|
export * from './controller/fetch_device_content';
|
|
17
17
|
export * from './controller/remote_error';
|
|
18
18
|
export * from './controller/notification_error';
|
|
19
|
+
export * from './close_error';
|
|
20
|
+
export * from './timeout_error';
|
|
19
21
|
|
|
20
22
|
import * as RemoteControlClasses from './controller/ControlClasses';
|
|
21
23
|
import * as Types from './types';
|
package/src/index.default.js
CHANGED
|
@@ -18,6 +18,8 @@ export * from './controller/PropertyObserver.js';
|
|
|
18
18
|
export * from './controller/fetch_device_content.js';
|
|
19
19
|
export * from './controller/remote_error.js';
|
|
20
20
|
export * from './controller/notification_error.js';
|
|
21
|
+
export * from './close_error.js';
|
|
22
|
+
export * from './timeout_error.js';
|
|
21
23
|
|
|
22
24
|
import * as RemoteControlClasses from './controller/ControlClasses.js';
|
|
23
25
|
import * as Types from './types.js';
|