X Tutup
# Using the brs-node Library This guide explains how to use the `brs-node` library in your Node.js applications and testing environments. The library provides programmatic access to the **BrightScript Simulation Engine**, allowing you to execute BrightScript code, run Roku applications, and test your BrightScript implementations. ## Table of Contents - [Using the brs-node Library](#using-the-brs-node-library) - [Table of Contents](#table-of-contents) - [Installation](#installation) - [Using in Node.js Applications](#using-in-nodejs-applications) - [Basic Setup](#basic-setup) - [Executing BrightScript Files](#executing-brightscript-files) - [Complete Example](#complete-example) - [Executing BrightScript from In-Memory Files](#executing-brightscript-from-in-memory-files) - [SceneGraph App Example](#scenegraph-app-example) - [Using the REPL Interpreter](#using-the-repl-interpreter) - [Handling Callbacks](#handling-callbacks) - [Working with SharedArrayBuffer](#working-with-sharedarraybuffer) - [Using in Tests](#using-in-tests) - [Setting up Jest Tests](#setting-up-jest-tests) - [Testing with E2E Helper Functions](#testing-with-e2e-helper-functions) - [Testing Best Practices](#testing-best-practices) - [1. Reset File System Between Tests](#1-reset-file-system-between-tests) - [2. Use Fake Timers for Time-Dependent Tests](#2-use-fake-timers-for-time-dependent-tests) - [3. Test with Deep Links](#3-test-with-deep-links) - [API Reference](#api-reference) - [Core Functions](#core-functions) - [`registerCallback(callback, sharedBuffer?)`](#registercallbackcallback-sharedbuffer) - [`createPayloadFromFiles(files, device, deepLink?, root?, ext?)`](#createpayloadfromfilesfiles-device-deeplink-root-ext) - [`createPayloadFromFileMap(fileMap, device, deepLink?)`](#createpayloadfromfilemapfilemap-device-deeplink) - [`executeFile(payload, options?)`](#executefilepayload-options) - [`getReplInterpreter(options)`](#getreplinterpreteroptions) - [`executeLine(line, interpreter)`](#executelineline-interpreter) - [File System API](#file-system-api) - [`BrsDevice.fileSystem.resetMemoryFS()`](#brsdevicefilesystemresetmemoryfs) - [Additional Resources](#additional-resources) - [Support](#support) --- ## Installation Install the package via npm: ```bash npm install brs-node ``` Or using yarn: ```bash yarn add brs-node ``` --- ## Using in Node.js Applications ### Basic Setup Import the library in your Node.js application: ```javascript const brs = require("brs-node"); ``` Or using ES6 imports (TypeScript): ```typescript import * as brs from "brs-node"; ``` ### Executing BrightScript Files The library provides several functions to execute BrightScript code. The main workflow involves: 1. Creating a payload from your BrightScript files 2. Registering a callback to handle output and events 3. Executing the payload #### Complete Example ```javascript const brs = require("brs-node"); const fs = require("fs"); const path = require("path"); // Register a callback to handle interpreter messages brs.registerCallback((message, data) => { if (typeof message === "string") { const [messageType, content] = message.split(",", 2); switch (messageType) { case "print": console.log(content); break; case "warning": console.warn(content); break; case "error": console.error(content); break; case "end": console.log(`Execution finished: ${content}`); break; } } else if (message instanceof Map) { // Registry updates console.log("Registry updated:", message); } }); // Define device configuration const deviceData = { developerId: "34c6fceca75e456f25e7e99531e2425c6c1de443", friendlyName: "BrightScript Test Device", deviceModel: "8000X", clientId: "6c5bf3a5-b2a5-4918-824d-7691d5c85364", RIDA: "f51ac698-bc60-4409-aae3-8fc3abc025c4", countryCode: "US", timeZone: "US/Eastern", locale: "en_US", clockFormat: "12h", displayMode: "1080p", customFeatures: [], localIps: ["192.168.1.100"], }; // Create payload from BrightScript files const files = [ path.join(__dirname, "main.brs"), path.join(__dirname, "lib", "utils.brs") ]; const payload = brs.createPayloadFromFiles( files, deviceData, new Map(), // deepLink parameters (optional) "/path/to/pkg/root", // root directory for pkg:/ (optional) "/path/to/ext/root" // root directory for ext1:/ (optional) ); // Execute the payload (async () => { try { const result = await brs.executeFile(payload); console.log(`Exit reason: ${result.exitReason}`); // Handle encrypted package generation if password was provided if (result.exitReason === "PACKAGED") { console.log("Package encrypted successfully"); // Save the encrypted package const encryptedData = new Uint8Array(result.cipherText); fs.writeFileSync("app.bpk", encryptedData); } } catch (error) { console.error("Execution failed:", error); } })(); ``` ### Executing BrightScript from In-Memory Files You can also create a payload from in-memory file content using `createPayloadFromFileMap`. This is useful when working with uploaded files, network resources, or dynamically generated content: ```javascript const brs = require("brs-node"); // Register callback (same as above) brs.registerCallback((message) => { // Handle messages... }); // Create file map with Blob content const fileMap = new Map(); // Add BrightScript source files const mainBrsCode = ` sub Main() print "Hello from in-memory BrightScript!" print "Device model: "; CreateObject("roDeviceInfo").GetModel() end sub `; fileMap.set("main.brs", new Blob([mainBrsCode], { type: "text/plain" })); // Add manifest file const manifestContent = ` title=My In-Memory App major_version=1 minor_version=0 build_version=1 `; fileMap.set("manifest", new Blob([manifestContent], { type: "text/plain" })); // Add additional library file const libCode = ` function GetAppVersion() as string return "1.0.1" end function `; fileMap.set("lib/utils.brs", new Blob([libCode], { type: "text/plain" })); // Execute the in-memory files (async () => { try { // Create payload from file map const payload = await brs.createPayloadFromFileMap(fileMap, deviceData); // Execute the payload const result = await brs.executeFile(payload); console.log(`Exit reason: ${result.exitReason}`); } catch (error) { console.error("Execution failed:", error); } })(); ``` #### SceneGraph App Example For SceneGraph applications, organize files in the proper folder structure: ```javascript const fileMap = new Map(); // Manifest for SceneGraph app const manifest = ` title=My SceneGraph App major_version=1 minor_version=0 ui_resolutions=hd splash_min_time=0 `; fileMap.set("manifest", new Blob([manifest], { type: "text/plain" })); // Main application source (executed) const mainCode = ` sub Main() print "SceneGraph app starting..." screen = CreateObject("roSGScreen") m.port = CreateObject("roMessagePort") screen.setMessagePort(m.port) scene = screen.CreateScene("MainScene") screen.show() print "Scene created and displayed" ' Event loop while true msg = wait(1000, m.port) if msg <> invalid if msg.isScreenClosed() exit while end if else exit while ' Timeout for demo end if end while end sub `; fileMap.set("source/main.brs", new Blob([mainCode], { type: "text/plain" })); // Scene component XML (packaged, not executed) const sceneXml = `
X Tutup