@scrypted/server 0.4.9 → 0.4.10
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.
Potentially problematic release.
This version of @scrypted/server might be problematic. Click here for more details.
- package/dist/event-registry.js +24 -10
- package/dist/event-registry.js.map +1 -1
- package/dist/media-helpers.js +4 -0
- package/dist/media-helpers.js.map +1 -1
- package/dist/plugin/plugin-device.js +5 -5
- package/dist/plugin/plugin-device.js.map +1 -1
- package/dist/plugin/plugin-host-api.js +18 -10
- package/dist/plugin/plugin-host-api.js.map +1 -1
- package/dist/plugin/plugin-lazy-remote.js +4 -2
- package/dist/plugin/plugin-lazy-remote.js.map +1 -1
- package/dist/plugin/plugin-remote.js +36 -16
- package/dist/plugin/plugin-remote.js.map +1 -1
- package/dist/plugin/system.js +2 -6
- package/dist/plugin/system.js.map +1 -1
- package/dist/rpc.js +3 -0
- package/dist/rpc.js.map +1 -1
- package/dist/services/plugin.js +2 -0
- package/dist/services/plugin.js.map +1 -1
- package/dist/state.js +57 -16
- package/dist/state.js.map +1 -1
- package/package.json +2 -2
- package/src/event-registry.ts +29 -10
- package/src/media-helpers.ts +5 -0
- package/src/plugin/plugin-api.ts +4 -0
- package/src/plugin/plugin-device.ts +5 -5
- package/src/plugin/plugin-host-api.ts +20 -10
- package/src/plugin/plugin-lazy-remote.ts +5 -3
- package/src/plugin/plugin-remote.ts +38 -18
- package/src/plugin/system.ts +2 -6
- package/src/rpc.ts +3 -0
- package/src/services/plugin.ts +2 -0
- package/src/state.ts +68 -20
package/src/plugin/system.ts
CHANGED
@@ -166,15 +166,11 @@ export class SystemManagerImpl implements SystemManager {
|
|
166
166
|
return this.events.listen(makeOneWayCallback((id, eventDetails, eventData) => callback(this.getDeviceById(id), eventDetails, eventData)));
|
167
167
|
}
|
168
168
|
listenDevice(id: string, options: string | EventListenerOptions, callback: EventListener): EventListenerRegister {
|
169
|
-
let {
|
170
|
-
if (!event && typeof options === 'string')
|
171
|
-
event = options as string;
|
172
|
-
if (!event)
|
173
|
-
event = undefined;
|
169
|
+
let { watch } = (options || {}) as EventListenerOptions;
|
174
170
|
|
175
171
|
// passive watching can be fast pathed to observe local state
|
176
172
|
if (watch)
|
177
|
-
return this.events.listenDevice(id,
|
173
|
+
return this.events.listenDevice(id, options, (eventDetails, eventData) => callback(this.getDeviceById(id), eventDetails, eventData));
|
178
174
|
|
179
175
|
return new EventListenerRegisterImpl(this.api.listenDevice(id, options, makeOneWayCallback((eventDetails, eventData) => callback(this.getDeviceById(id), eventDetails, eventData))));
|
180
176
|
}
|
package/src/rpc.ts
CHANGED
@@ -154,6 +154,9 @@ class RpcProxy implements PrimitiveProxyHandler<any> {
|
|
154
154
|
|
155
155
|
if (this.proxyOneWayMethods?.includes?.(method)) {
|
156
156
|
rpcApply.oneway = true;
|
157
|
+
// a oneway callable object doesn't need to be in the JSON payload.
|
158
|
+
if (method === null)
|
159
|
+
delete rpcApply.method;
|
157
160
|
this.peer.send(rpcApply, undefined, serializationContext);
|
158
161
|
return Promise.resolve();
|
159
162
|
}
|
package/src/services/plugin.ts
CHANGED
@@ -70,6 +70,8 @@ export class PluginComponent {
|
|
70
70
|
async kill(pluginId: string) {
|
71
71
|
return this.scrypted.plugins[pluginId]?.kill();
|
72
72
|
}
|
73
|
+
// TODO: Remove this, ScryptedPlugin exists now.
|
74
|
+
// 12/29/2022
|
73
75
|
async getPackageJson(pluginId: string) {
|
74
76
|
return this.scrypted.getPackageJson(pluginId);
|
75
77
|
}
|
package/src/state.ts
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
import { EventDetails, EventListenerOptions, EventListenerRegister, Refresh, ScryptedInterface, ScryptedInterfaceProperty, ScryptedNativeId, SystemDeviceState } from "@scrypted/types";
|
2
2
|
import throttle from 'lodash/throttle';
|
3
3
|
import { PluginDevice } from "./db-types";
|
4
|
-
import { EventListenerRegisterImpl, EventRegistry } from "./event-registry";
|
5
|
-
import {
|
6
|
-
import { RefreshSymbol } from "./plugin/plugin-device";
|
4
|
+
import { EventListenerRegisterImpl, EventRegistry, getMixinEventName } from "./event-registry";
|
5
|
+
import { propertyInterfaces } from "./plugin/descriptor";
|
6
|
+
import { QueryInterfaceSymbol, RefreshSymbol } from "./plugin/plugin-device";
|
7
7
|
import { ScryptedRuntime } from "./runtime";
|
8
8
|
import { sleep } from "./sleep";
|
9
9
|
|
@@ -34,25 +34,74 @@ export class ScryptedStateManager extends EventRegistry {
|
|
34
34
|
this.scrypted = scrypted;
|
35
35
|
}
|
36
36
|
|
37
|
-
|
38
|
-
|
37
|
+
async getImplementerId(pluginDevice: PluginDevice, eventInterface: ScryptedInterface | string) {
|
38
|
+
if (!eventInterface)
|
39
|
+
throw new Error(`ScryptedInterface is required`);
|
40
|
+
|
41
|
+
const device = this.scrypted.getDevice(pluginDevice._id);
|
39
42
|
if (!device)
|
40
|
-
throw new Error(`device
|
41
|
-
|
43
|
+
throw new Error(`device ${pluginDevice._id} not found?`);
|
44
|
+
|
45
|
+
const implementerId: string = await (device as any)[QueryInterfaceSymbol](eventInterface);
|
46
|
+
return implementerId;
|
47
|
+
}
|
48
|
+
|
49
|
+
async notifyInterfaceEventFromMixin(pluginDevice: PluginDevice, eventInterface: ScryptedInterface | string, value: any, mixinId: string) {
|
50
|
+
// TODO: figure out how to clean this up this hack. For now,
|
51
|
+
// Settings interface is allowed to bubble from mixin devices..
|
52
|
+
if (eventInterface !== ScryptedInterface.Settings) {
|
53
|
+
const implementerId = await this.getImplementerId(pluginDevice, eventInterface);
|
54
|
+
if (implementerId !== mixinId) {
|
55
|
+
const event = getMixinEventName({
|
56
|
+
event: eventInterface,
|
57
|
+
mixinId,
|
58
|
+
});
|
59
|
+
|
60
|
+
this.notifyEventDetails(pluginDevice._id, {
|
61
|
+
eventId: undefined,
|
62
|
+
eventInterface,
|
63
|
+
eventTime: Date.now(),
|
64
|
+
mixinId,
|
65
|
+
}, value, event);
|
66
|
+
|
67
|
+
return;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
this.notify(pluginDevice?._id, Date.now(), eventInterface, undefined, value);
|
72
|
+
}
|
73
|
+
|
74
|
+
async setPluginDeviceStateFromMixin(pluginDevice: PluginDevice, property: string, value: any, eventInterface: ScryptedInterface, mixinId: string) {
|
75
|
+
const implementerId = await this.getImplementerId(pluginDevice, eventInterface);
|
76
|
+
if (implementerId !== mixinId) {
|
77
|
+
const event = getMixinEventName({
|
78
|
+
event: eventInterface,
|
79
|
+
mixinId,
|
80
|
+
});
|
81
|
+
this.scrypted.getDeviceLogger(pluginDevice).log('i', `${property}: ${value} (mixin)`);
|
82
|
+
this.notifyEventDetails(pluginDevice._id, {
|
83
|
+
eventId: undefined,
|
84
|
+
eventInterface,
|
85
|
+
eventTime: Date.now(),
|
86
|
+
mixinId,
|
87
|
+
property,
|
88
|
+
}, value, event);
|
89
|
+
return false;
|
90
|
+
}
|
91
|
+
|
92
|
+
return this.setPluginDeviceState(pluginDevice, property, value, eventInterface);
|
42
93
|
}
|
43
94
|
|
44
95
|
setPluginDeviceState(device: PluginDevice, property: string, value: any, eventInterface?: ScryptedInterface) {
|
45
96
|
eventInterface = eventInterface || propertyInterfaces[property];
|
46
97
|
if (!eventInterface)
|
47
|
-
throw new Error(
|
98
|
+
throw new Error(`eventInterface must be provided`);
|
48
99
|
|
49
100
|
const changed = setState(device, property, value);
|
50
101
|
|
51
|
-
const eventTime = device?.state?.[property]?.lastEventTime;
|
52
|
-
|
53
102
|
if (eventInterface !== ScryptedInterface.ScryptedDevice) {
|
54
|
-
if (this.notify(device?._id,
|
55
|
-
this.scrypted.getDeviceLogger(device).log('i',
|
103
|
+
if (this.notify(device?._id, Date.now(), eventInterface, property, value, { changed }) && device) {
|
104
|
+
this.scrypted.getDeviceLogger(device).log('i', `${property}: ${value}`);
|
56
105
|
}
|
57
106
|
}
|
58
107
|
|
@@ -63,15 +112,18 @@ export class ScryptedStateManager extends EventRegistry {
|
|
63
112
|
}
|
64
113
|
|
65
114
|
updateDescriptor(device: PluginDevice) {
|
66
|
-
this.notify(device._id, undefined, ScryptedInterface.ScryptedDevice, undefined, device.state, true);
|
115
|
+
this.notify(device._id, undefined, ScryptedInterface.ScryptedDevice, undefined, device.state, { changed: true });
|
67
116
|
}
|
68
117
|
|
69
118
|
removeDevice(id: string) {
|
70
|
-
this.notify(undefined, undefined, ScryptedInterface.ScryptedDevice, ScryptedInterfaceProperty.id, id, true);
|
119
|
+
this.notify(undefined, undefined, ScryptedInterface.ScryptedDevice, ScryptedInterfaceProperty.id, id, { changed: true });
|
71
120
|
}
|
72
121
|
|
73
|
-
notifyInterfaceEvent(device: PluginDevice, eventInterface: ScryptedInterface | string, value: any) {
|
74
|
-
this.notify(device?._id, Date.now(), eventInterface, undefined, value,
|
122
|
+
notifyInterfaceEvent(device: PluginDevice, eventInterface: ScryptedInterface | string, value: any, mixinId?: string) {
|
123
|
+
this.notify(device?._id, Date.now(), eventInterface, undefined, value, {
|
124
|
+
changed: true,
|
125
|
+
mixinId,
|
126
|
+
});
|
75
127
|
}
|
76
128
|
|
77
129
|
setState(id: string, property: string, value: any) {
|
@@ -214,12 +266,8 @@ export function setState(pluginDevice: PluginDevice, property: string, value: an
|
|
214
266
|
if (!pluginDevice.state[property])
|
215
267
|
pluginDevice.state[property] = {};
|
216
268
|
const state = pluginDevice.state[property];
|
217
|
-
const now = Date.now();
|
218
269
|
const changed = !isSameValue(value, state.value);
|
219
|
-
if (changed)
|
220
|
-
state.stateTime = now;
|
221
270
|
state.value = value;
|
222
|
-
state.lastEventTime = now;
|
223
271
|
return changed;
|
224
272
|
}
|
225
273
|
|