esmodule plugins: wip

This commit is contained in:
Koushik Dutta
2024-11-30 09:09:38 -08:00
parent 71bb2ec80a
commit 73d2f5b408
6 changed files with 67 additions and 25 deletions

View File

@@ -10,8 +10,12 @@ const config = defineConfig({
output: {
sourcemap: true,
file: `${process.env.NODE_ENV === 'production' ? 'dist' : 'out'}/main.nodejs.js`,
format: 'cjs',
format: 'module',
banner: `//# sourceURL=/plugin/main.nodejs.js`,
},
external: [
'unifi-protect',
],
plugins: [
virtual({

View File

@@ -17,28 +17,28 @@ export class ScryptedDeviceBase extends DeviceBase {
get storage() {
if (!this._storage) {
this._storage = deviceManager.getDeviceStorage(this.nativeId);
this._storage = sdk.deviceManager.getDeviceStorage(this.nativeId);
}
return this._storage;
}
get log() {
if (!this._log) {
this._log = deviceManager.getDeviceLogger(this.nativeId);
this._log = sdk.deviceManager.getDeviceLogger(this.nativeId);
}
return this._log;
}
get console() {
if (!this._console) {
this._console = deviceManager.getDeviceConsole(this.nativeId);
this._console = sdk.deviceManager.getDeviceConsole(this.nativeId);
}
return this._console;
}
async createMediaObject(data: any, mimeType: string) {
return mediaManager.createMediaObject(data, mimeType, {
return sdk.mediaManager.createMediaObject(data, mimeType, {
sourceId: this.id,
});
}
@@ -46,16 +46,16 @@ export class ScryptedDeviceBase extends DeviceBase {
getMediaObjectConsole(mediaObject: MediaObject): Console | undefined {
if (typeof mediaObject.sourceId !== 'string')
return this.console;
return deviceManager.getMixinConsole(mediaObject.sourceId, this.nativeId);
return sdk.deviceManager.getMixinConsole(mediaObject.sourceId, this.nativeId);
}
_lazyLoadDeviceState() {
if (!this._deviceState) {
if (this.nativeId) {
this._deviceState = deviceManager.getDeviceState(this.nativeId);
this._deviceState = sdk.deviceManager.getDeviceState(this.nativeId);
}
else {
this._deviceState = deviceManager.getDeviceState();
this._deviceState = sdk.deviceManager.getDeviceState();
}
}
}
@@ -64,7 +64,7 @@ export class ScryptedDeviceBase extends DeviceBase {
* Fire an event for this device.
*/
onDeviceEvent(eventInterface: string, eventData: any): Promise<void> {
return deviceManager.onDeviceEvent(this.nativeId, eventInterface, eventData);
return sdk.deviceManager.onDeviceEvent(this.nativeId, eventInterface, eventData);
}
}
@@ -100,14 +100,14 @@ export class MixinDeviceBase<T> extends DeviceBase implements DeviceState {
this.mixinDeviceInterfaces = options.mixinDeviceInterfaces;
this.mixinStorageSuffix = options.mixinStorageSuffix;
this._deviceState = options.mixinDeviceState;
this.nativeId = systemManager.getDeviceById(this.id).nativeId;
this.nativeId = sdk.systemManager.getDeviceById(this.id).nativeId;
this.mixinProviderNativeId = options.mixinProviderNativeId;
// RpcProxy will trap all properties, and the following check/hack will determine
// if the device state came from another node worker thread.
// This should ultimately be discouraged and warned at some point in the future.
if ((this._deviceState as any).__rpcproxy_traps_all_properties && typeof this._deviceState.id === 'string') {
this._deviceState = deviceManager.createDeviceState(this._deviceState.id, this._deviceState.setState);
this._deviceState = sdk.deviceManager.createDeviceState(this._deviceState.id, this._deviceState.setState);
}
}
@@ -115,24 +115,24 @@ export class MixinDeviceBase<T> extends DeviceBase implements DeviceState {
if (!this._storage) {
const mixinStorageSuffix = this.mixinStorageSuffix;
const mixinStorageKey = this.id + (mixinStorageSuffix ? ':' + mixinStorageSuffix : '');
this._storage = deviceManager.getMixinStorage(mixinStorageKey, this.mixinProviderNativeId);
this._storage = sdk.deviceManager.getMixinStorage(mixinStorageKey, this.mixinProviderNativeId);
}
return this._storage;
}
get console() {
if (!this._console) {
if (deviceManager.getMixinConsole)
this._console = deviceManager.getMixinConsole(this.id, this.mixinProviderNativeId);
if (sdk.deviceManager.getMixinConsole)
this._console = sdk.deviceManager.getMixinConsole(this.id, this.mixinProviderNativeId);
else
this._console = deviceManager.getDeviceConsole(this.mixinProviderNativeId);
this._console = sdk.deviceManager.getDeviceConsole(this.mixinProviderNativeId);
}
return this._console;
}
async createMediaObject(data: any, mimeType: string) {
return mediaManager.createMediaObject(data, mimeType, {
return sdk.mediaManager.createMediaObject(data, mimeType, {
sourceId: this.id,
});
}
@@ -140,14 +140,14 @@ export class MixinDeviceBase<T> extends DeviceBase implements DeviceState {
getMediaObjectConsole(mediaObject: MediaObject): Console {
if (typeof mediaObject.sourceId !== 'string')
return this.console;
return deviceManager.getMixinConsole(mediaObject.sourceId, this.mixinProviderNativeId);
return sdk.deviceManager.getMixinConsole(mediaObject.sourceId, this.mixinProviderNativeId);
}
/**
* Fire an event for this device.
*/
onDeviceEvent(eventInterface: string, eventData: any): Promise<void> {
return deviceManager.onMixinEvent(this.id, this, eventInterface, eventData);
return sdk.deviceManager.onMixinEvent(this.id, this, eventInterface, eventData);
}
_lazyLoadDeviceState() {
@@ -201,15 +201,16 @@ export class MixinDeviceBase<T> extends DeviceBase implements DeviceState {
}
})();
export const sdk: ScryptedStatic = {} as any;
declare const deviceManager: DeviceManager;
declare const endpointManager: EndpointManager;
declare const mediaManager: MediaManager;
declare const systemManager: SystemManager;
declare const pluginHostAPI: any;
declare const pluginRuntimeAPI: any;
export const sdk: ScryptedStatic = {} as any;
try {
let runtimeAPI: any;
try {
runtimeAPI = pluginRuntimeAPI;
@@ -217,7 +218,7 @@ try {
catch (e) {
}
Object.assign(sdk, {
sdkInit({
log: deviceManager.getDeviceLogger(undefined),
deviceManager,
endpointManager,
@@ -234,7 +235,29 @@ try {
}
}
catch (e) {
console.error('sdk initialization error, import @scrypted/types or use @scrypted/client instead', e);
// console.error('sdk initialization error, import @scrypted/types or use @scrypted/client instead', e);
}
export default sdk;
export function sdkInit(sdkInit: {
deviceManager: DeviceManager,
endpointManager: EndpointManager,
mediaManager: MediaManager,
systemManager: SystemManager,
pluginHostAPI: any,
pluginRuntimeAPI: any,
}) {
const { deviceManager, endpointManager, mediaManager, systemManager, pluginHostAPI, pluginRuntimeAPI } = sdkInit;
Object.assign(sdk, {
log: deviceManager.getDeviceLogger(undefined),
deviceManager,
endpointManager,
mediaManager,
systemManager,
pluginHostAPI,
...pluginRuntimeAPI,
});
}

View File

@@ -5,7 +5,7 @@
"version": "0.2.0",
"configurations": [
{
"autoAttachChildProcesses": false,
"autoAttachChildProcesses": true,
"type": "node",
"request": "launch",
"name": "Launch Program",

5
server/es-eval.js Normal file
View File

@@ -0,0 +1,5 @@
export async function eseval(script) {
// const dataUrl = `data:text/javascript,${encodeURIComponent(script)}`;
const module = await import(script);
return module;
}

View File

@@ -24,6 +24,8 @@ import { NodeThreadWorker } from './runtime/node-thread-worker';
import { prepareZip } from './runtime/node-worker-common';
import { getBuiltinRuntimeHosts } from './runtime/runtime-host';
import { RuntimeWorker, RuntimeWorkerOptions } from './runtime/runtime-worker';
// @ts-expect-error
import { eseval } from '../../es-eval.js';
const serverVersion = require('../../package.json').version;
@@ -360,9 +362,17 @@ export function startPluginRemote(mainFilename: string, pluginId: string, peerSe
try {
const filename = zipOptions?.debug ? pluginMainNodeJs : pluginIdMainNodeJs;
evalLocal(peer, script, startPluginRemoteOptions?.sourceURL?.(filename) || filename, params);
if (packageJson.type === 'module') {
const p = path.join(unzippedPath, mainNodejs);
const module = await eseval(p);
params.module.exports = module;
}
else {
evalLocal(peer, script, startPluginRemoteOptions?.sourceURL?.(filename) || filename, params);
}
const exports = params.module.exports;
exports.sdkInit?.(params);
if (zipOptions?.fork) {
// pluginConsole?.log('plugin forked');
const fork = exports.fork;

View File

@@ -9,9 +9,9 @@
// skip error: Interface 'WebGL2RenderingContext' incorrectly extends interface 'WebGL2RenderingContextBase'.
// https://github.com/tensorflow/tfjs/issues/4201
"skipLibCheck": true,
"sourceMap": true
"sourceMap": true,
},
"include": [
"src/**/*"
"src/**/*", "es-eval.js",
],
}