diff --git a/plugins/core/.vscode/launch.json b/plugins/core/.vscode/launch.json index 03660e3c27..e8f5f98901 100644 --- a/plugins/core/.vscode/launch.json +++ b/plugins/core/.vscode/launch.json @@ -10,14 +10,14 @@ "port": 10081, "request": "attach", "skipFiles": [ - "**/plugin-remote-worker.*", + "**/plugin-console.*", "/**" ], "preLaunchTask": "scrypted: deploy+debug", "sourceMaps": true, "localRoot": "${workspaceFolder}/out", "remoteRoot": "/plugin/", - "type": "pwa-node" + "type": "node" } ] } \ No newline at end of file diff --git a/plugins/core/.vscode/settings.json b/plugins/core/.vscode/settings.json index 79c8960630..d10219dfb0 100644 --- a/plugins/core/.vscode/settings.json +++ b/plugins/core/.vscode/settings.json @@ -1,3 +1,3 @@ { - "scrypted.debugHost": "127.0.0.1", + "scrypted.debugHost": "scrypted-server", } \ No newline at end of file diff --git a/plugins/core/package-lock.json b/plugins/core/package-lock.json index 667ec817f0..da38483349 100644 --- a/plugins/core/package-lock.json +++ b/plugins/core/package-lock.json @@ -1,12 +1,12 @@ { "name": "@scrypted/core", - "version": "0.1.150", + "version": "0.2.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@scrypted/core", - "version": "0.1.150", + "version": "0.2.1", "license": "Apache-2.0", "dependencies": { "@scrypted/common": "file:../../common", diff --git a/plugins/core/package.json b/plugins/core/package.json index 99bd1ea37c..66108982eb 100644 --- a/plugins/core/package.json +++ b/plugins/core/package.json @@ -1,6 +1,6 @@ { "name": "@scrypted/core", - "version": "0.1.150", + "version": "0.2.1", "description": "Scrypted Core plugin. Provides the UI, websocket, and engine.io APIs.", "author": "Scrypted", "license": "Apache-2.0", diff --git a/plugins/core/src/builtins/timer.ts b/plugins/core/src/builtins/timer.ts deleted file mode 100644 index 38e1f97b53..0000000000 --- a/plugins/core/src/builtins/timer.ts +++ /dev/null @@ -1,3 +0,0 @@ -export class Timer { - -} \ No newline at end of file diff --git a/plugins/core/src/main.ts b/plugins/core/src/main.ts index 2551b7ec90..43a88b4b4e 100644 --- a/plugins/core/src/main.ts +++ b/plugins/core/src/main.ts @@ -9,14 +9,12 @@ import { AggregateCore, AggregateCoreNativeId } from './aggregate-core'; import { AutomationCore, AutomationCoreNativeId } from './automations-core'; import { LauncherMixin } from './launcher-mixin'; import { MediaCore } from './media-core'; -import { ScriptCore, ScriptCoreNativeId } from './script-core'; -import { UsersCore, UsersNativeId } from './user'; +import { newScript, ScriptCore, ScriptCoreNativeId } from './script-core'; import { TerminalService, TerminalServiceNativeId } from './terminal-service'; +import { UsersCore, UsersNativeId } from './user'; const { systemManager, deviceManager, endpointManager } = sdk; -const indexHtml = fs.readFileSync('dist/index.html').toString(); - export function getAddresses() { const addresses: string[] = []; for (const [iface, nif] of Object.entries(os.networkInterfaces())) { @@ -61,10 +59,14 @@ class ScryptedCore extends ScryptedDeviceBase implements HttpRequestHandler, Eng }, } }); + indexHtml: string; constructor() { super(); + + this.indexHtml = fs.readFileSync('dist/index.html').toString(); + (async () => { await deviceManager.onDeviceDiscovered( { @@ -226,7 +228,7 @@ class ScryptedCore extends ScryptedDeviceBase implements HttpRequestHandler, Eng const endpoint = await endpointManager.getPublicCloudEndpoint(); const u = new URL(endpoint); - const rewritten = indexHtml + const rewritten = this.indexHtml .replace('href="manifest.json"', `href="manifest.json${u.search}"`) .replace('href="img/icons/apple-touch-icon-152x152.png"', `href="img/icons/apple-touch-icon-152x152.png${u.search}"`) .replace('href="img/icons/safari-pinned-tab.svg"', `href="img/icons/safari-pinned-tab.svg${u.search}"`) @@ -269,5 +271,6 @@ export default ScryptedCore; export async function fork() { return { tsCompile, + newScript, } -} \ No newline at end of file +} diff --git a/plugins/core/src/script-core.ts b/plugins/core/src/script-core.ts index 41dc8d796d..55490a6447 100644 --- a/plugins/core/src/script-core.ts +++ b/plugins/core/src/script-core.ts @@ -1,33 +1,24 @@ -import { Device, DeviceCreator, DeviceCreatorSettings, DeviceProvider, Readme, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, Setting } from "@scrypted/sdk"; +import { Device, DeviceCreator, DeviceCreatorSettings, DeviceProvider, Readme, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, ScryptedNativeId, Setting } from "@scrypted/sdk"; import { Script } from "./script"; import sdk from '@scrypted/sdk'; import { randomBytes } from "crypto"; import fs from 'fs'; import path from "path/posix"; +import { Worker } from "worker_threads"; const { deviceManager } = sdk; export const ScriptCoreNativeId = 'scriptcore'; +interface ScriptWorker { + script: Script; + worker: Worker; +} + export class ScriptCore extends ScryptedDeviceBase implements DeviceProvider, DeviceCreator, Readme { - scripts = new Map>(); + scripts = new Map(); constructor() { super(ScriptCoreNativeId); - - for (const nativeId of deviceManager.getNativeIds()) { - if (nativeId?.startsWith('script:')) { - const script = new Script(nativeId); - this.scripts.set(nativeId, (async () => { - if (script.providedInterfaces.length > 2) { - await script.run(); - } - else { - this.reportScript(nativeId); - } - return script; - })()); - } - } } async getCreateDeviceSettings(): Promise { @@ -65,7 +56,6 @@ export class ScriptCore extends ScryptedDeviceBase implements DeviceProvider, De catch (e) { } } - this.scripts.set(nativeId, Promise.resolve(script)); return nativeId; } @@ -84,10 +74,38 @@ export class ScriptCore extends ScryptedDeviceBase implements DeviceProvider, De return await deviceManager.onDeviceDiscovered(device); } - getDevice(nativeId: string) { - return this.scripts.get(nativeId); + async getDevice(nativeId: string) { + const e = this.scripts.get(nativeId); + if (e) + return e; + let script = new Script(nativeId); + let worker: Worker; + if (script.providedInterfaces.length > 2) { + const fork = sdk.fork<{ + newScript: typeof newScript, + }>(); + worker = fork.worker + try { + script = await (await fork.result).newScript(nativeId); + await script.run(); + } + catch (e) { + worker.terminate(); + throw e; + } + } + this.scripts.set(nativeId, { + script, + worker, + }); + return script; } async releaseDevice(id: string, nativeId: string): Promise { + this.scripts.get(nativeId)?.worker?.terminate(); } } + +export async function newScript(nativeId: ScryptedNativeId) { + return new Script(nativeId); +} diff --git a/plugins/core/src/script.ts b/plugins/core/src/script.ts index 8ff96958ce..6c78fa408f 100644 --- a/plugins/core/src/script.ts +++ b/plugins/core/src/script.ts @@ -5,7 +5,7 @@ import { createScriptDevice, ScriptDeviceImpl } from "@scrypted/common/src/eval/ import { ScriptCoreNativeId } from "./script-core"; import { PluginAPIProxy } from "../../../server/src/plugin/plugin-api"; -const { log, deviceManager, systemManager } = sdk; +const { deviceManager } = sdk; export class Script extends ScryptedDeviceBase implements Scriptable, Program, ScriptDeviceImpl { apiProxy: PluginAPIProxy; diff --git a/plugins/core/ui/src/interfaces/CameraViewer.vue b/plugins/core/ui/src/interfaces/CameraViewer.vue index e391a4860c..f7823fbaa4 100644 --- a/plugins/core/ui/src/interfaces/CameraViewer.vue +++ b/plugins/core/ui/src/interfaces/CameraViewer.vue @@ -169,7 +169,7 @@ export default { const fs = 20; - const box = ` + const box = ` ${t} ${t} `; diff --git a/plugins/core/ui/src/interfaces/ObjectDetection.vue b/plugins/core/ui/src/interfaces/ObjectDetection.vue index b8e8c5112e..0574a5f78c 100644 --- a/plugins/core/ui/src/interfaces/ObjectDetection.vue +++ b/plugins/core/ui/src/interfaces/ObjectDetection.vue @@ -45,7 +45,7 @@ export default { for (const detection of this.lastDetection.detections || []) { if (!detection.boundingBox) continue; const svgScale = this.svgWidth / 1080; - const sw = 6 * svgScale; + const sw = 1; const s = "red"; const x = detection.boundingBox[0]; const y = detection.boundingBox[1];