-
Notifications
You must be signed in to change notification settings - Fork 2
URSYS Addons Framework
Tip
For a quickstart developing your own addons, see ursys-x-sna-addon
Addons live in the _ur_addons
directory as "mini projects" that can import the @ursys/core
library and build more specialized features. They're designed for both command line and browser use.
An addon directory is used for self-contained features that are built around "pure data" or "utility data transformation" that is written in platform-independent Typescript. This library can be imported directly on the server-side using an "entryfile" that lives in addon directory (see COMMAND LINE USE below) or exported as a package "@ursys/addons" library for both server and client platforms by adding it to @addon-client.ts
or @addon-server.mts
respectively.
Let's add an addon directory to work in!
- open a VSCODE integrated terminal and
cd _ur
- open another VSCODE integrated terminal and
cd _ur_addons
- create an empty directory
foo
inside_ur_addons
In the _ur
terminal, type ur
by itself. You'll see that the 'foo' addon has been added. If you type ur foo
, you will get an error because there is no "entryfile". Let's fix that!
- in the
foo
directory, create the file@foo-test.mts
Back in the _ur
terminal, type ur foo
and you will no longer see an error, though nothing interesting is happening. Let's add a console.log statement
- open
@foo-test.mts
and addconsole.log(process.argv)
Now when you type ur foo
, you'll see the arguments that have been passed to @foo-test.mts
when it was forked. Try adding more arguments to the command line:
ur foo this --flag=poop "Sally Johnson"
You'll see that all the arguments are passed from the command line to your @foo-test.mts
script. You could parse these commands to do different things based on what you've passed.
Now let's create and import a typescript library.
- create a file inside
foo
calledbar-lib.ts
. Add the lines:export function Bar() { console.log('barbar'); }
- in
@foo-test.mts
:- at the top add
import pkg_bar from './bar-lib.ts'
- add
const {Bar} = pkg;
next. - at the bottom, add
Bar();
- at the top add
NOTE: if you're not familiar with Typescript, bear with this for now. Step 7's instructions are due to the imperfect meshing of Typescript with NodeJS at this time.
Now when you type ur foo
, you'll see barbar
also appear.
Finally, let's add a second entry point, which is useful for when you want to use the libraries in different ways, or perhaps want to include an entirely different utility inside your foo
addon.
- In the
foo
directory, create the file@zoop.cjs
(note the different extension).
When you type ur foo
, the system will find the first alphabetically-listed file in the directory that begins with @
. To run the new entry point, use this syntax:
ur foo@zoop
You'll see that nothing is really happening, because there is nothing in the @zoom.cjs
file unless you added something yourself! Since this is a CommonJS file (evidenced by the .cjs
extension), we can use the old-style NodeJS syntax for importing modules.
- In
@zoom.cjs
add these lines:const { PR } = require('@ursys/core');
const TERM = PR('ZoopCJS','TagBlue');
TERM('Hello from @zoop.cjs');
Now when you type ur foo@zoop
, you'll see some formatted text in the terminal.
A few things to note:
- A
.cjs
file usesrequire
module syntax (commonjs module) - A
.mts
file usesimport
module syntax (typescript module)
Tip
The various nuances of cross-compatibility between the four kinds of Node JS files, Typescript, and different platform contexts is extremely confusing. If you are also learning Typescript, it is even more confusing. It's not just you!
The ur
command line utility executes from within the _ur
directory. It scans the _ur_addons
directory for addons; these are simply directories that don't have a leading underscore. For example. to run the command-line version of an addon in the _ur_addons/midi
directory, you'd type:
ur midi
You can also just type ur
by itself and it will list the directories it finds in _ur_addons
.
The ur
utility looks inside the addon subdirectory for directories, skipping ones that begin with an underscore. It then looks for the first matching file that begins with @
; these are "entryfiles" that will be forked as an independent process. You can also specifiy which entryfile if you like. For example:
ur foo
ur foo@entryfile
Currently we are using .mts
(node typescript modules) for our entry files. You do not need to include the extension when designating the entryfile.
After you've written your pure Typescript implementation, you can include it in one of two files:
-
_ur_addons/@addon-client.ts
- the client-side entry point for bundle generation -
_ur_addons/@addon-server.mts
- the server-side entry point for bundle generation
You would write a platform-specific library that wraps your pure typescript library for the specific needs of that platform, or choose to export it directly. The bundling operation is handled by the ur build
command, creating files according to the _ur_addons/package.json
exports and mainfiles properties. The libraries are exported in multiple formats for UMD, CommonJS, AMD, and ESM uses.
To use the library, you currently have to install it as a dependency using file:
urls. For example, if you have the _ur
and _ur_addons
directories in your main app with its own package.json
in the root, you would add the packages as follows:
npm i @ursys/core ../_ur
npm i @ursys/addons ../_ur_addons
After this, you should be able to require
or import
the @ursys/core
and @ursys/addon
libraries into your codebase. The method you use depends on what build system your main app uses. URSYS has its own self-contained build system that is independent of yours.
Q. Why are my import * as UR from '@ursys/core'
statements showing red? It still runs!
A. This might be because of Visual Studio's Typescript Language Server being confused. If you don't see any obvious path errors (missing .ts
extension, wrong number of ..
, etc), try resaving the _ur_addons/tsconfig.json
file to see if it goes away; this forces the internals to refresh...we think. Even opening the tsconfig.json
file will invalidate all types...we think.