From b7da8ac9b7a507147892ace354ba9fde0ead6a84 Mon Sep 17 00:00:00 2001 From: chuck-dbos <134347445+chuck-dbos@users.noreply.github.com> Date: Mon, 24 Jun 2024 18:55:29 -0400 Subject: [PATCH] Auto-register (#142) Signed-off-by: chuck-dbos <134347445+chuck-dbos@users.noreply.github.com> Co-authored-by: Qian Li Co-authored-by: Peter Kraft --- docs/api-reference/cli.md | 2 +- docs/api-reference/communicatorlib.md | 10 ++-------- docs/api-reference/testing-runtime.md | 13 +++++++++---- .../application-structure-explanation.md | 7 ++++--- docs/tutorials/testing-tutorial.md | 6 +++++- docs/tutorials/using-libraries.md | 12 ------------ 6 files changed, 21 insertions(+), 29 deletions(-) diff --git a/docs/api-reference/cli.md b/docs/api-reference/cli.md index 24fb6a8b..4cbb052f 100644 --- a/docs/api-reference/cli.md +++ b/docs/api-reference/cli.md @@ -14,7 +14,7 @@ The DBOS Transact CLI helps you run applications locally. **Description:** This command launches the DBOS Transact runtime and HTTP server to serve an application. -It registers all functions and serves all endpoints in classes exported by the [declared entrypoint files](./configuration#runtime) (`dist/operations.js` by default). +It registers all functions and serves all endpoints in classes and dependencies of the [declared entrypoint files](./configuration#runtime) (`dist/operations.js` by default). Parameters set from the command line take precedence over parameters set in the [configuration file](./configuration). You must compile your code (`npm run build`) before running this command. diff --git a/docs/api-reference/communicatorlib.md b/docs/api-reference/communicatorlib.md index a1952a96..592c39b0 100644 --- a/docs/api-reference/communicatorlib.md +++ b/docs/api-reference/communicatorlib.md @@ -21,13 +21,6 @@ npm install --save @dbos-inc/communicator-datetime Import the communicator into your TypeScript code: ```typescript import { CurrentTimeCommunicator } from '@dbos-inc/communicator-datetime'; -export { CurrentTimeCommunicator }; // Currently necessary for registration to see the class -``` - -For DBOS to register the communicator functions, it is currently necessary for the communicator to be exported from your `operations.ts` file (as it would be for any other communicator). -If the code using the communicator is not in `operations.ts`, add a line to export the communicator from `operations.ts` also. -```typescript -export { CurrentTimeCommunicator } from '@dbos-inc/communicator-datetime'; ``` Invoke the communicator from a `WorkflowContext`: @@ -37,7 +30,8 @@ const curDate = await wfCtx.invoke(CurrentTimeCommunicator).getCurrentDate(); When using the DBOS testing runtime, if you are explicitly providing the list of classes to register, it will be necessary to register any library communicator classes also: ```typescript - testRuntime = await createTestingRuntime([Operations, CurrentTimeCommunicator], "dbos-config.yaml"); + testRuntime = await createTestingRuntime(); // No explicit registration, classes referenced by test will be registered + testRuntime = await createTestingRuntime([Operations, CurrentTimeCommunicator], "dbos-config.yaml"); // Specify everything ``` --- diff --git a/docs/api-reference/testing-runtime.md b/docs/api-reference/testing-runtime.md index b4af11d8..f100e341 100644 --- a/docs/api-reference/testing-runtime.md +++ b/docs/api-reference/testing-runtime.md @@ -19,15 +19,20 @@ When writing tests, you are responsible for setting up and cleaning up your data ## Create Testing Runtime -### createTestingRuntime(userClasses, \[configFilePath\]) +### createTestingRuntime(\[userClasses\], \[configFilePath\]) ```typescript -async function createTestingRuntime(userClasses: object[], configFilePath: string = dbosConfigFilePath): Promise +async function createTestingRuntime(userClasses: object[] | undefined = undefined, configFilePath: string = dbosConfigFilePath): Promise ``` -Creates a testing runtime and loads user functions from provided `userClasses`. +Creates a testing runtime and loads user functions from provided `userClasses`. By default, all classes and dependencies from the test file are loaded and registered. Accepts an optional path to a [configuration file](./configuration.md), uses the default path (`dbos-config.yaml` in the package root) otherwise. -For example, to create a runtime loading functions from the `Hello` class and using `test-config.yaml`: +The defaults are generally sufficient as long as classes are at least indirectly referenced from the test file: +```typescript +testRuntime = await createTestingRuntime(); +``` + +However, to explicitly create a runtime loading functions from the `Hello` class and using `test-config.yaml`: ```typescript testRuntime = await createTestingRuntime([Hello], "test-config.yaml"); ``` diff --git a/docs/explanations/application-structure-explanation.md b/docs/explanations/application-structure-explanation.md index fa925d1b..1947cb5e 100644 --- a/docs/explanations/application-structure-explanation.md +++ b/docs/explanations/application-structure-explanation.md @@ -34,7 +34,7 @@ The two most important files in a DBOS project are `dbos-config.yaml` and `src/o All options are documented in our [configuration reference](../api-reference/configuration). `src/operations.ts` is the _entrypoint_, where DBOS looks for your code. -At startup, the DBOS runtime automatically loads all classes exported from this file, serving their endpoints and registering their decorated functions. +At startup, the DBOS runtime automatically loads all classes that are exported or (directly and indirectly) referenced from this file, serving their endpoints and registering their decorated functions. More precisely, DBOS assumes your compiled code is exported from `dist/operations.js`, the default location to which `src/operations.ts` is compiled. If you're writing a small application, you can write all your code directly in this file. In a larger application, you can write your code wherever you want, but should use `src/operations.ts` as an index file, exporting code written elsewhere: @@ -43,7 +43,8 @@ In a larger application, you can write your code wherever you want, but should u export { OperationClass1, OperationClass2 } from './FileA'; export { OperationClass3 } from './operations/FileB'; ``` -You can also configure a list of entrypoints using the `runtimeConfig` section of the [configuration](../api-reference/configuration#runtime). +It is not necessary to export classes that are already referenced by the entrypoint file(s), as these will be loaded and decorated methods will be registered. +You can also define multiple entrypoint files using the `runtimeConfig` section of the [configuration](../api-reference/configuration#runtime). As for the rest of the directory: @@ -94,7 +95,7 @@ There are two more: A function needs to follow a few rules: -- It must be a static class method. For DBOS to find it, that class must be exported from `src/operations.ts`. +- It must be a static class method. For DBOS to find it, that class must be exported or referenced from `src/operations.ts` (or another file in the `runtimeConfig.entrypoints` list). - It must have a decorator telling the framework what kind of function it is: [`@Transaction`](../api-reference/decorators#transaction) for transactions, [`@Communicator`](../api-reference/decorators#communicator) for communicators, [`@Workflow`](../api-reference/decorators#workflow) for workflows, or [`GetApi`](../api-reference/decorators#getapi) or [`PostApi`](../api-reference/decorators#postapi) for HTTP handlers. - Its first argument must be the appropriate kind of [context](../api-reference/contexts). Contexts provide useful methods, such as access to a database client for transactions. - Its input and return types must be serializable to JSON. diff --git a/docs/tutorials/testing-tutorial.md b/docs/tutorials/testing-tutorial.md index f85079f6..a5bc2089 100644 --- a/docs/tutorials/testing-tutorial.md +++ b/docs/tutorials/testing-tutorial.md @@ -16,9 +16,13 @@ We use [Jest](https://jestjs.io/) in this example, but the testing runtime works First, let's create a `TestingRuntime` object: ```typescript +testRuntime = await createTestingRuntime(); +``` + +This function optionally takes in a list of classes you want to test. Here, we want to test the methods of the `Hello` class, so we could have specified: +```typescript testRuntime = await createTestingRuntime([Hello]); ``` -This function takes in a list of classes you want to test. Here, we want to test the methods of the `Hello` class. You can also optionally provide a path to a [configuration file](../api-reference/configuration.md). If no path is provided, the runtime loads a configuration file from the default location (`dbos-config.yaml` in the package root). diff --git a/docs/tutorials/using-libraries.md b/docs/tutorials/using-libraries.md index d3766fcf..bcdc05cd 100644 --- a/docs/tutorials/using-libraries.md +++ b/docs/tutorials/using-libraries.md @@ -18,18 +18,6 @@ Second, import the key classes from the library for use in your source files: import { SendEmailCommunicator } from "@dbos-inc/communicator-email-ses"; ``` -### Exporting Library Classes -:::tip -Do not forget to export all classes containing handlers, transactions, workflows, and communicators from your main application file, otherwise DBOS Transact functions may not be registered with the runtime. -::: - -To export the library from your `index.ts` file, add the following: -```typescript title="index.ts" -export { SendEmailCommunicator }; -// or -export { SendEmailCommunicator } from "@dbos-inc/communicator-email-ses"; -``` - ### Calling Simple Functions Libraries such as `@dbos-inc/communicator-bcrypt` or `@dbos-inc/communicator-datetime` are comprised of functions that can be invoked from their classes. Using the context (named `ctx` below), the `invoke` method can be used to call the library function: ```typescript