### Install Project Dependencies (npm install) Source: https://docs.rootapp.com/docs/app-docs/tutorials/showdown-app/generate-build-test-app Install all the necessary Node.js packages required for your Root application by running the `npm i` command within your project's root directory. This ensures all dependencies are available for building and running. ```bash npm i ``` -------------------------------- ### App Manifest Structure Example Source: https://docs.rootapp.com/docs/app-docs/configure/manifest-reference This is a complete example of an App manifest file, illustrating the overall structure and the placement of key properties like id, version, and package configurations for both client and server. ```json { "id": "ACj4U-eThgmjXUOBAjk_jw", "version": "1.0.0", "package": { "client": { "deploy": "client/dist" }, "server": { "launch": "server/dist/myServerMain.js", "deploy": [ "server/dist", "networking/gen/server" ], "node_modules": [ "server/node_modules" ] } } } ``` -------------------------------- ### Example Root App Initialization and Cleanup Source: https://docs.rootapp.com/docs/app-docs/develop/server/server-lifecycle An example demonstrating how to import Root APIs, initialize services and databases in the `onStarting` callback, and log an error in the `onStopping` callback. It shows a typical registration of `onStarting` and `onStopping` callbacks. ```typescript // Import Root APIs import { rootServer, RootAppStartState } from "@rootsdk/server-app"; // Import your initialization functions import { initializeMyService } from "./myService"; import { initializeMyDatabase } from "./myDatabase"; // Define your start callback async function onStarting(state: RootAppStartState) { await initializeMyDatabase(); await initializeMyService(); } // Define your stop callback async function onStopping() { const request: CommunityAppLogCreateRequest = { communityAppLogType: CommunityAppLogType.Error, message: "your-message-to-the-community-goes-here" }; await rootServer.datastore.logs.community.create(request); } (async () => { // Register your callbacks, typically only onStarting and onStopping are needed await rootServer.lifecycle.start(onStarting, onStopping); })(); ``` -------------------------------- ### App Manifest: Package Property Example Source: https://docs.rootapp.com/docs/app-docs/configure/manifest-reference Example of the 'package' property within an App manifest. This object contains deployment and startup configuration for both client and server components of your application. ```json { "package": { "client": { "deploy": "client/dist" }, "server": { "launch": "server/dist/myAppMain.js", "deploy": [ "server/dist", "networking/gen/server" ], "node_modules": [ "server/node_modules" ] } } } ``` -------------------------------- ### Install Project Dependencies with npm Source: https://docs.rootapp.com/docs/app-docs/get-started/build-your-app Installs the necessary packages for your Root App project. This command should be run from the root of your App's project folder. ```bash npm i ``` -------------------------------- ### Root Manifest JSON Example Source: https://docs.rootapp.com/docs/app-docs/configure/manifest-overview A basic example of the Root manifest file structure in JSON format. This file defines essential application details and integration points for the Root platform. ```json { "App": "TBD" } ``` -------------------------------- ### App Manifest: Client Deploy Path Example Source: https://docs.rootapp.com/docs/app-docs/configure/manifest-reference Example for the 'deploy' property under the 'client' object in an App manifest. This string specifies the path to the client-side build output directory relative to the project root. ```string "client/dist" ``` -------------------------------- ### Set, Get, and Update User XP with KeyValueStore in JavaScript Source: https://docs.rootapp.com/docs/app-docs/develop/server/persistence/persistence-key-value-store This example demonstrates how to use the KeyValueStore to implement a simple leveling system by storing and updating user experience points. It shows setting an initial value, retrieving it, and updating it using a provided function. The KeyValueStore is accessed through `rootServer.dataStore.appData`. ```javascript import { rootServer } from "@rootsdk/server-app"; const userId: string = "..."; // You'd retrieve the userId from the incoming community message // Set user XP to 100 await rootServer.dataStore.appData.set({ key: userId, value: 100, }); // Get user XP const xp: number = await rootServer.dataStore.appData.get(userId) ?? 0; // Add 50 XP const updatedXp: number = await rootServer.dataStore.appData.update( userId, (currentXp) => currentXp + 50, // Update function 0 // Default XP to pass to update function if this userId isn't set yet ); ``` -------------------------------- ### App Manifest: Server Deploy Paths Example Source: https://docs.rootapp.com/docs/app-docs/configure/manifest-reference Example for the 'deploy' property under the 'server' object in an App manifest. This array lists the server folders that should be included in the deployment package. ```json [ "server/dist", "networking/gen/server" ] ``` -------------------------------- ### Implement Root App Starting Callback Source: https://docs.rootapp.com/docs/app-docs/develop/server/server-lifecycle Defines the `onStarting` callback function, which receives a `RootAppStartState` object containing community information and global settings. This function is intended for all initialization tasks. ```typescript import { RootAppStartState } from "@rootsdk/server-app"; async function onStarting(state: RootAppStartState) { // Do all your initialization here } ``` -------------------------------- ### Upload Package to Root Cloud CLI Example Source: https://docs.rootapp.com/docs/app-docs/publish/upload This example demonstrates how to use the `rootsdk upload package` command to deploy a package file to the Root cloud. It requires specifying the path to the package file and a valid authentication token, typically provided via an environment variable. ```shell rootsdk upload package \ --file ./dist/rootapp-1-2-3.pkg \ --auth-token $TOKEN ``` -------------------------------- ### Create Root App using CLI Source: https://docs.rootapp.com/docs/app-docs/get-started/generate-app-starter-code Use the `npx create-root` command to generate starter code for a new Root application. This command requires a project name as a parameter. Ensure Node.js and npx are installed. ```bash npx create-root --app ``` ```bash npx create-root --app MyApp ``` -------------------------------- ### Launch App Client with Vite (npm/bash) Source: https://docs.rootapp.com/docs/app-docs/get-started/test-your-app This command starts the development server for your App's client using Vite. Navigate to your App's 'client' folder before running this command. You can run this multiple times to test different community members simultaneously. ```bash npm run client ``` -------------------------------- ### Run Root Application Server (npm run server) Source: https://docs.rootapp.com/docs/app-docs/tutorials/showdown-app/generate-build-test-app Start the server-side component of your Root application locally. This command executes the server code, which requires a valid `DEV_TOKEN` for communication. ```bash npm run server ``` -------------------------------- ### Example Options Configuration Source: https://docs.rootapp.com/docs/app-docs/configure/manifest-reference This snippet demonstrates the structure of an options object, which can include various data types for user-facing settings. It shows examples of string-based options, timestamp objects, date objects, and color pickers, along with default values. ```json { "label": "Low", "value": "low", "timestamp": { "$date": "2025-08-05T00:00:00Z" }, "time": { "defaultValue": "09:30:00" }, "date": { "$date": "2025-08-05" }, "color": { "defaultValue": "#ff0000" }, "button": { "title": "Reset settings" } } ``` -------------------------------- ### Example JSON for Checkbox Configuration Source: https://docs.rootapp.com/docs/app-docs/configure/manifest-reference Provides an example of how to configure a boolean checkbox input. The primary configuration option is the default state of the checkbox. ```json { "key": "enableFeatureX", "title": "Enable Feature X", "required": false, "confirmation": "Save", "checkbox": { "defaultValue": true } } ``` -------------------------------- ### Example JSON for Property Group Source: https://docs.rootapp.com/docs/app-docs/configure/manifest-reference Demonstrates the structure of a property group, including its key, title, and a list of individual items. Each item has its own key, title, and optional description. ```json { "key": "general", "title": "General Settings", "items": [ { "key": "maxRaidSize", "title": "Maximum raid size", "description": "Set the upper limit for raid participants.", "required": true, "confirmation": "Save" }, { "key": "notifyOnJoin", "title": "Notify on new join", "required": false, "confirmation": "Update" } ] } ``` -------------------------------- ### App Manifest: Settings Property Example Source: https://docs.rootapp.com/docs/app-docs/configure/manifest-reference Example of the optional 'settings' property in an App manifest. This object defines configurable global settings that can be adjusted by community administrators. ```json { "groups": [ { "key": "general", "title": "General", "items": [ { "key": "notifyOnJoin", "title": "Notify on new join", "description": "Send a message when someone joins the raid.", "required": false, "confirmation": "Update", "checkbox": { "defaultValue": true } } ] } ] } ``` -------------------------------- ### Start Root Server Lifecycle (JavaScript) Source: https://docs.rootapp.com/docs/app-docs/get-started/test-your-app This JavaScript snippet represents the entry-point for your App's server, which is called by the DevHost. It initiates the server's lifecycle using the rootServer.lifecycle.start() method. Ensure the rootServer object is correctly imported and configured. ```javascript await rootServer.lifecycle.start(); ``` -------------------------------- ### Example JSON for Number Input Configuration Source: https://docs.rootapp.com/docs/app-docs/configure/manifest-reference Shows the structure for configuring a numeric input field. This includes optional settings for minimum value, maximum value, step increment, and a default value. ```json { "key": "timeoutSeconds", "title": "Timeout (seconds)", "required": true, "confirmation": "Apply", "number": { "minValue": 5, "maxValue": 300, "step": 5, "defaultValue": 60 } } ``` -------------------------------- ### Define Server Entry Point in root-manifest.json Source: https://docs.rootapp.com/docs/app-docs/develop/server/server-lifecycle This JSON configuration specifies the main server entry point file for your application. The 'launch.server' property points to the compiled JavaScript file (e.g., 'server/dist/main.js') that Root will execute to start your server. ```json { "name": "MyName", "description": "My description", "version": "1.0.0", "launch": { "server": "server/dist/main.js" } } ``` -------------------------------- ### Initializing Root Server Application in TypeScript Source: https://docs.rootapp.com/docs/app-docs/develop/networking/implement-service This TypeScript code sets up the main entry point for the Root server application. It imports necessary modules, defines an initialization function to add services to the Root lifecycle, and starts the server. ```typescript import { rootServer, RootStartState } from "@rootsdk/server-app"; import { suggestionService } from "./suggestionService"; async function initialize(state: RootStartState) { rootServer.lifecycle.addService(suggestionService); // Register your instance with Root } (async () => { await rootServer.lifecycle.start(initialize); })(); ``` -------------------------------- ### Run RootApp client using npm run client Source: https://docs.rootapp.com/docs/app-docs/tutorials/tasks-app/in-memory This command starts the client-side development server for the RootApp application. It is executed from the 'client' subfolder of the project. ```bash npm run client ``` -------------------------------- ### Run RootApp server using npm run server Source: https://docs.rootapp.com/docs/app-docs/tutorials/tasks-app/in-memory This command starts the server-side component of the RootApp application. It is executed from the 'server' subfolder of the project. ```bash npm run server ``` -------------------------------- ### Register Root App Lifecycle Callbacks Source: https://docs.rootapp.com/docs/app-docs/develop/server/server-lifecycle Demonstrates various ways to call `rootServer.lifecycle.start` and register lifecycle callbacks: with no callbacks, only the starting callback, skipping unneeded callbacks by passing `undefined`, and registering all three callbacks. ```typescript import { rootServer, RootAppStartState } from "@rootsdk/server-app"; async function onStarting(state: RootAppStartState) { // Do all your initialization here } async function onStopping() { // Do your main cleanup here } async function onStopped() { // Do any last-second cleanup here } (async () => { // Various ways to call start await rootServer.lifecycle.start(); // No callbacks await rootServer.lifecycle.start(onStarting); // Starting callback only await rootServer.lifecycle.start(onStarting, undefined, onStopped); // Pass undefined to skip unneeded callbacks await rootServer.lifecycle.start(onStarting, onStopping, onStopped); // All })(); ``` -------------------------------- ### Full root-protoc.json Configuration Options Source: https://docs.rootapp.com/docs/app-docs/develop/networking/generate-service This example demonstrates a comprehensive `root-protoc.json` configuration, specifying source files, proto import paths, output directory, NPM scope, and custom package names for client, server, and shared generated code. ```json { "source": ["./**/*.proto"], "protoPaths": ["./src"], "outDir": "./gen", "scope": "@suggestionbox", "clientPackageName": "gen-client", "serverPackageName": "gen-server", "sharedPackageName": "gen-shared" } ``` -------------------------------- ### Example Permissions Configuration Source: https://docs.rootapp.com/docs/app-docs/configure/manifest-reference This code illustrates how to define specific permissions required for the RootApp application. It includes channel-level permissions such as viewing and full control, as well as various community-level permissions like kicking, banning, and managing channel groups. ```json { "permissions": { "channel": { "channelFullControl": true, "channelView": true }, "community": { "communityFullControl": false, "communityChangeMyNickname": true, "communityChangeOtherNickname": false, "communityCreateBan": true, "communityCreateChannelGroup": true, "communityCreateInvite": true, "communityKick": true, "communityManageApps": true } } } ``` -------------------------------- ### Example JSON for Text Input Configuration Source: https://docs.rootapp.com/docs/app-docs/configure/manifest-reference Illustrates the configuration for a free-form text input field within a settings group. It includes optional properties for a default value and a regular expression for validation. ```json { "key": "customTitle", "title": "Custom Title", "description": "Enter a custom title for the section.", "required": true, "confirmation": "Set", "text": { "defaultValue": "Enter a title...", "regex": "^[a-zA-Z0-9 ]+" } } ``` -------------------------------- ### Package Project from Different Directory with Custom Output Source: https://docs.rootapp.com/docs/app-docs/publish/package This example demonstrates packaging a project located in a different directory (`../my-project`) than the current one, while also specifying a custom output file path (`./dist/pkg`). The `--project-folder` option targets the source manifest, and `--output-file` determines the destination. ```bash rootsdk build package --project-folder ../my-project --output-file ./dist/pkg ``` -------------------------------- ### Generate App Starter Code with create-root CLI Source: https://docs.rootapp.com/docs/app-docs/tutorials/showdown-app/generate-build-test-app Use the `create-root` command-line utility to generate the initial file structure and starter code for a new Root application. This command initializes the project in a specified directory. ```bash npx create-root --app ``` -------------------------------- ### Build Root Application (npm run build) Source: https://docs.rootapp.com/docs/app-docs/tutorials/showdown-app/generate-build-test-app Compile your Root application's client, server, and networking code. The `npm run build` command processes `.proto` files, generates networking code, and compiles all components. ```bash npm run build ``` -------------------------------- ### App Manifest: Server Node Modules Paths Example Source: https://docs.rootapp.com/docs/app-docs/configure/manifest-reference Example for the 'node_modules' property under the 'server' object in an App manifest. This array specifies server-side node_modules folders that are required for deployment. ```json [ "server/node_modules" ] ``` -------------------------------- ### App Manifest: ID Property Example Source: https://docs.rootapp.com/docs/app-docs/configure/manifest-reference Example demonstrating the required 'id' property for an App manifest. This unique identifier is obtained from the Root Developer Portal and is crucial for identifying your application. ```json { "id": "ACj4U-eThgmjXUOBAjk_jw" } ``` -------------------------------- ### App Manifest: Version Property Example Source: https://docs.rootapp.com/docs/app-docs/configure/manifest-reference Example showing the required 'version' property in an App manifest. This semantic version string (MAJOR.MINOR.PATCH) must be unique for each release to ensure proper version management. ```json { "version": "1.0.0" } ``` -------------------------------- ### Get Window Size and Subscribe to Resize Events (JavaScript) Source: https://docs.rootapp.com/docs/app-docs/develop/client/responsive-ui This snippet demonstrates how to get the current inner width and height of the browser window and how to subscribe to the 'resize' event to log new dimensions when the window size changes. This is crucial for implementing responsive UIs in Root apps. ```javascript const width = window.innerWidth; const height = window.innerHeight; window.addEventListener('resize', () => { console.log(window.innerWidth, window.innerHeight); }); ``` -------------------------------- ### Build Root App with npm Source: https://docs.rootapp.com/docs/app-docs/get-started/build-your-app Compiles your Root App's source code (client, networking, and server). This command generates the client in `client/dist` and the server in `server/dist`. ```bash npm run build ``` -------------------------------- ### Server Example: Throwing Custom Exception on Deletion Failure (TypeScript) Source: https://docs.rootapp.com/docs/app-docs/develop/networking/handle-exceptions This TypeScript example shows a server-side implementation of a 'delete' method within a 'SuggestionService'. It checks if a suggestion was found and deleted; if not, it throws a RootServerException with a custom error code (SuggestionBoxError.NOT_FOUND) and a specific message. ```typescript export class SuggestionService extends SuggestionServiceBase { // ... async delete(request: SuggestionDeleteRequest, client: Client): Promise { const affectedRows: number = await suggestionRepository.delete(request.id); if (affectedRows === 0) { const message: string = "SuggestionService.delete: attempt to delete non-existent suggestion."; console.error(message); throw new RootServerException(SuggestionBoxError.NOT_FOUND, message); } const event: SuggestionDeletedEvent = { id: request.id }; this.broadcastDeleted(event, "all", client); const response: SuggestionDeleteResponse = {}; // Intentionally empty return response; } } ``` -------------------------------- ### Build and Run Root App Client with Vite Source: https://docs.rootapp.com/docs/app-docs/develop/client/client-project-overview Configuration for building and locally testing the Root App client using Vite. These scripts are defined in the client's package.json file. The 'build' script compiles TypeScript and creates a production build with Vite, while the 'client' script starts the Vite development server for local testing. ```json { "scripts": { "build": "tsc && vite build", "client": "vite" } } ``` -------------------------------- ### Launch App Server with DevHost (npm/bash) Source: https://docs.rootapp.com/docs/app-docs/get-started/test-your-app This command launches your App's server within the Root DevHost environment. Ensure you are in the 'server' folder of your App and have a valid DEV_TOKEN configured. The DevHost reads the entry-point from 'root-manifest.json'. ```bash npm run server ``` ```bash rootsdk start devhost --project-folder=../ ``` -------------------------------- ### Protobuf Enum Usage in a Message Source: https://docs.rootapp.com/docs/app-docs/develop/networking/define-service Demonstrates how to use a defined protobuf enum as a field type within a message. This example shows the 'Category' enum being used in the 'Suggestion' message to categorize suggestions. ```protobuf enum Category { CATEGORY_UNKNOWN = 0; CATEGORY_ENGINEERING = 1; CATEGORY_BILLING = 2; CATEGORY_MARKETING = 3; } message Suggestion { uint32 id = 1; string author_id = 2; string text = 3; repeated string voter_ids = 4; rootsdk.Timestamp created_at = 5; Category category = 6; } ``` -------------------------------- ### Extending SuggestionServiceBase in TypeScript Source: https://docs.rootapp.com/docs/app-docs/develop/networking/implement-service This TypeScript code shows a minimal example of extending the generated SuggestionServiceBase class. It imports the base class and defines a new class 'SuggestionService' that inherits from it, preparing it for further implementation. ```typescript import { SuggestionServiceBase } from "@suggestionbox/gen-server"; export class SuggestionService extends SuggestionServiceBase { } ``` -------------------------------- ### Initialize Prisma in Main Application Entry Point Source: https://docs.rootapp.com/docs/app-docs/tutorials/tasks-app/prisma This TypeScript code demonstrates how to call the `initializePrisma` function within the `onStarting` lifecycle hook in `server/src/main.ts`. This ensures that the database is set up and ready before the task service is added as a service to the Root application. ```typescript import { rootServer, RootAppStartState } from "@rootsdk/server-app"; import { taskService } from "./taskService"; //import { initializeKnex } from "./knexTaskRepository"; import { initializePrisma } from "./prismaTaskRepository"; async function onStarting(state: RootAppStartState) { //await initializeKnex(); await initializePrisma(); rootServer.lifecycle.addService(taskService); } (async () => { await rootServer.lifecycle.start(onStarting); })(); ``` -------------------------------- ### Configure Development Token (.env file) Source: https://docs.rootapp.com/docs/app-docs/tutorials/showdown-app/generate-build-test-app Add your generated `DEV_TOKEN` to the `.env` file located in the `server` directory. This token is essential for server-side authentication during local development and testing. ```env DEV_TOKEN=ACROZj4Ilajlkgjoilkjdljfb5l2jln426k42548fdlj4359204undlajf_lkaejrln3904280294FLWalPd35aoier82m_lkad4lkjas0kj-aeheccewqioclbaljer34akjwqpz_-lk-kO52jQjlaljbjlk5299elk2aklbwpcast67lka0as2lgxlmqJSO98absLa34s90gask2ac ``` -------------------------------- ### Basic Usage of Rootsdk Build Package Command Source: https://docs.rootapp.com/docs/app-docs/publish/package Demonstrates the fundamental usage of the `rootsdk build package` command. This command packages the current project into a default output file named `rootapp-.pkg` located in the project root. No additional options are required for basic packaging. ```bash rootsdk build package ``` -------------------------------- ### Package.json Dependencies for Root SDK Source: https://docs.rootapp.com/docs/app-docs/tutorials/showdown-app/initial-state Updates the dependencies in the package.json file to include generated client, server, and shared modules from the Root SDK, using a specified scope for generated code. This ensures the project can utilize the generated networking code. ```json { "dependencies": { "@rootsdk/client-app": "*", "@rootsdk/server-app": "*", "@showdown/gen-client": "file:./networking/gen/client", "@showdown/gen-server": "file:./networking/gen/server", "@showdown/gen-shared": "file:./networking/gen/shared" } } ``` -------------------------------- ### Protobuf Service Definition for SuggestionBox Source: https://docs.rootapp.com/docs/app-docs/get-started/app-overview Defines a Protobuf service for suggestion-related remote procedure calls (RPCs). The `Create` method specifies the request and response types for creating a suggestion. Root tooling generates client and server stubs from this definition. ```protobuf service SuggestionService { rpc Create(SuggestionCreateRequest) returns (SuggestionCreateResponse); // ... } ``` -------------------------------- ### Install Rootsdk Dev Tools for Packaging Source: https://docs.rootapp.com/docs/app-docs/publish/package This snippet shows how to add the `@rootsdk/dev-tools` package as a development dependency in your project's `package.json` file. This is required to use the `rootsdk build package` command. Ensure your npm or yarn client is configured correctly. ```json { "devDependencies": { "@rootsdk/dev-tools": "*" } } ``` -------------------------------- ### Customize Output Directory for Root Package Source: https://docs.rootapp.com/docs/app-docs/publish/package This example shows how to specify a custom output directory for the generated package file using the `--output-file` option. The package will be created in the `./dist` directory with a default file name derived from the manifest version. ```bash rootsdk build package --output-file ./dist ``` -------------------------------- ### Build RootApp using npm run build Source: https://docs.rootapp.com/docs/app-docs/tutorials/tasks-app/in-memory This command builds the React application for production deployment. It is executed from the project's root directory and prepares the client-side assets. ```bash npm run build ```