add some comments, bump to rc4

This commit is contained in:
Matt Hill
2023-05-03 16:09:32 -06:00
parent 9a1dd5a399
commit 0ddd35c8d7
14 changed files with 127 additions and 43 deletions

View File

@@ -1,5 +1,4 @@
import { DeepPartial, Dependencies, Effects, ExpectedExports } from "../types"
import { InputSpec } from "./configTypes"
import { Effects, ExpectedExports } from "../types"
import { SDKManifest } from "../manifest/ManifestTypes"
import * as D from "./dependencies"
import { Config, ExtractConfigType } from "./builder/config"

View File

@@ -1,6 +1,5 @@
import { ManifestVersion } from "../../manifest/ManifestTypes"
import { Effects } from "../../types"
import { Utils } from "../../util"
export class Migration<Version extends ManifestVersion> {
constructor(

View File

@@ -19,27 +19,26 @@ type Daemon<Ids extends string, Command extends string, Id extends string> = {
type ErrorDuplicateId<Id extends string> = `The id '${Id}' is already used`
/**
* Used during the main of a function, it allows us to describe and ensure a set of daemons are running.
* With the dependency, we are using this like an init system, where we can ensure that a daemon is running
* The return type of this is used in the runningMain
* A class for defining and controlling the service daemons
```ts
Daemons.with({
effects,
started,
interfacesReceipt,
})
.addDaemon({
id: "nostr",
command: "./nostr-rs-relay --db /data",
ready: {
display: {
name: "Websocket Live",
message: "The websocket is live",
},
fn: () => checkPortListening(effects, 8080),
},
})
.build()
Daemons.of({
effects,
started,
interfaceReceipt, // Provide the interfaceReceipt to prove it was completed
healthReceipts, // Provide the healthReceipts or [] to prove they were at least considered
}).addDaemon('webui', {
command: 'hello-world', // The command to start the daemon
ready: {
display: 'Web Interface',
// The function to run to determine the health status of the daemon
fn: () =>
checkPortListening(effects, 80, {
successMessage: 'The web interface is ready',
errorMessage: 'The web interface is not ready',
}),
},
requires: [],
})
```
*/
export class Daemons<Ids extends string> {
@@ -48,7 +47,16 @@ export class Daemons<Ids extends string> {
readonly started: (onTerm: () => void) => null,
readonly daemons?: Daemon<Ids, "command", Ids>[],
) {}
/**
* Returns an empty new Daemons class with the provided config.
*
* Call .addDaemon() on the returned class to add a daemon.
*
* Daemons run in the order they are defined, with latter daemons being capable of
* depending on prior daemons
* @param config
* @returns
*/
static of(config: {
effects: Effects
started: (onTerm: () => void) => null
@@ -57,6 +65,12 @@ export class Daemons<Ids extends string> {
}) {
return new Daemons<never>(config.effects, config.started)
}
/**
* Returns the complete list of daemons, including the one defined here
* @param id
* @param newDaemon
* @returns
*/
addDaemon<Id extends string, Command extends string>(
// prettier-ignore
id:

View File

@@ -1,5 +1,4 @@
import { Effects } from "../types"
import { LocalPort } from "./LocalPort"
import { TorHostname } from "./TorHostname"
export class NetworkBuilder {

View File

@@ -2,6 +2,17 @@ import { Effects } from "../types"
import { AddressReceipt } from "./AddressReceipt"
import { Origin } from "./Origin"
/**
* A helper class for creating a Network Interface
*
* Network Interfaces are collections of web addresses that expose the same API or other resource,
* display to the user with under a common name and description.
*
* All URIs on an interface inherit the same ui: bool, basic auth credentials, path, and search (query) params
*
* @param options
* @returns
*/
export class NetworkInterfaceBuilder {
constructor(
readonly options: {
@@ -16,6 +27,14 @@ export class NetworkInterfaceBuilder {
},
) {}
/**
* A function to register a group of origins (<PROTOCOL> :// <HOSTNAME> : <PORT>) with StartOS
*
* The returned addressReceipt serves as proof that the addresses were registered
*
* @param addresses
* @returns
*/
async exportAddresses(addresses: Iterable<Origin>) {
const { name, description, id, ui, path, search } = this.options
for (const origin of addresses) {

View File

@@ -1,6 +1,11 @@
import { AddressReceipt } from "./AddressReceipt"
import { InterfaceReceipt } from "./interfaceReceipt"
/**
* Takes a list of addressReceipts
*
* Returns an interfaceReceipt, which is needed to create the service daemons
*/
export const exportInterfaces = (
_firstProof: AddressReceipt,
..._rest: AddressReceipt[]

View File

@@ -19,7 +19,10 @@ export interface SDKManifest {
id: string
/** A human readable service title */
title: string
/** Service version - accepts up to four digits, where the last confirms to revisions necessary for StartOs - see documentation: https://github.com/Start9Labs/emver-rs. This value will change with each release of the service */
/** Service version - accepts up to four digits, where the last confirms to revisions necessary for StartOs
* - see documentation: https://github.com/Start9Labs/emver-rs. This value will change with each release of
* the service
*/
version: ManifestVersion
/** Release notes for the update - can be a string, paragraph or URL */
releaseNotes: string
@@ -27,7 +30,10 @@ export interface SDKManifest {
license: string // name of license
/** A list of normie (hosted, SaaS, custodial, etc) services this services intends to replace */
replaces: string[]
/** The Start9 wrapper repository URL for the package. This repo contains the manifest file (this), any scripts necessary for configuration, backups, actions, or health checks (more below). This key must exist. But could be embedded into the source repository */
/** The Start9 wrapper repository URL for the package. This repo contains the manifest file (this),
* any scripts necessary for configuration, backups, actions, or health checks (more below). This key
* must exist. But could be embedded into the source repository
*/
wrapperRepo: string
/** The original project repository URL. There is no upstream repo in this example */
upstreamRepo: string
@@ -44,15 +50,18 @@ export interface SDKManifest {
/** This description will display with additional details in the service's individual marketplace page */
long: string
}
/** These assets are static files necessary for packaging the service for Start9 (into an s9pk). Each value is a path to the specified asset. If an asset is missing from this list, or otherwise denoted, it will be defaulted to the values denoted below. */
/** These assets are static files necessary for packaging the service for Start9 (into an s9pk).
* Each value is a path to the specified asset. If an asset is missing from this list, or otherwise
* denoted, it will be defaulted to the values denoted below.
*/
assets: {
icon: string // file path
instructions: string // file path
license: string // file path
}
/**Defines the containers needed to run the main and mounted volumes */
/** Defines the containers needed to run the main and mounted volumes */
containers: Record<string, Container>
/**This denotes any data, asset, or pointer volumes that should be connected when the "docker run" command is invoked */
/** This denotes any data, asset, or pointer volumes that should be connected when the "docker run" command is invoked */
volumes: Record<string, string>
actions: Array<ActionMetaData>
alerts: {
@@ -68,7 +77,8 @@ export interface SDKManifest {
export interface Dependency {
/** The range of versions that would satisfy the dependency
* ie: >=3.4.5 && <4.0.0
*
* ie: >=3.4.5 <4.0.0
*/
version: string
/**

View File

@@ -2,8 +2,16 @@ import { PackagePropertyGroup } from "../types"
import { PropertyPage } from "./PropertyPage"
import { PropertyString } from "./PropertyString"
/**
* A Property Group is a list of values, separated from other property groups by a whitespace divider with an optional header
*/
export class PropertyGroup {
private constructor(readonly data: PackagePropertyGroup) {}
/**
* Returns a new Property Group with the provided options
* @param options
* @returns
*/
static of(options: {
header: string | null
values: (PropertyPage | PropertyString)[]

View File

@@ -1,8 +1,18 @@
import { PackagePropertyPage } from "../types"
import { PropertyGroup } from "./PropertyGroup"
/**
* A Property Page will display to the user as a button with a name a description.
* Clicking the button will take the user to a nested page displaying the provided
* list of Property Groups
*/
export class PropertyPage {
private constructor(readonly data: PackagePropertyPage) {}
/**
* Returns a new Property Page with the provided options
* @param options
* @returns
*/
static of(options: {
name: string
description: string | null

View File

@@ -1,8 +1,16 @@
import { PackagePropertyString } from "../types"
/**
* A Property String is an arbitrary string value to display to the user
*/
export class PropertyString {
private constructor(readonly data: PackagePropertyString) {}
static of(value: Omit<PackagePropertyString, "type" | "watch">) {
/**
* Returns a new Property String with the provided options
* @param value
* @returns
*/
static of(value: Omit<PackagePropertyString, "type">) {
return new PropertyString({
...value,
type: "string",

View File

@@ -3,8 +3,8 @@ import { Effects } from "../types"
export class GetSystemSmtp {
constructor(readonly effects: Effects) {}
/** This should be used as the primary method in main since it allows the main to
* restart if the wrapper data changes
/**
* Returns the system SMTP credentials. Restarts the service if the credentials change
*/
const() {
return this.effects.getSystemSmtp({
@@ -12,8 +12,7 @@ export class GetSystemSmtp {
})
}
/**
* Returns the wrapper data once and then never again
* Doesn't restart the server when the wrapper data changes
* Returns the system SMTP credentials. Does nothing if the credentials change
*/
once() {
return this.effects.getSystemSmtp({
@@ -21,7 +20,7 @@ export class GetSystemSmtp {
})
}
/**
* Keeps giving the latest wrapper data as it changes
* Watches the system SMTP credentials. Takes a custom callback function to run whenever the credentials change
*/
async *watch() {
while (true) {

View File

@@ -89,6 +89,11 @@ export class FileHelper<A> {
}),
)
}
/**
* Create a File Helper for an arbitrary file type.
*
* Provide custom functions for translating data to the file format and visa versa.
*/
static raw<A>(
path: string,
volume: string,
@@ -97,6 +102,9 @@ export class FileHelper<A> {
) {
return new FileHelper<A>(path, volume, toFile, fromFile)
}
/**
* Create a File Helper for a .json file
*/
static json<A>(
path: string,
volume: string,
@@ -113,6 +121,9 @@ export class FileHelper<A> {
},
)
}
/**
* Create a File Helper for a .toml file
*/
static toml<A extends Record<string, unknown>>(
path: string,
volume: string,
@@ -129,6 +140,9 @@ export class FileHelper<A> {
},
)
}
/**
* Create a File Helper for a .yaml file
*/
static yaml<A extends Record<string, unknown>>(
path: string,
volume: string,

View File

@@ -12,8 +12,8 @@ export class GetWrapperData<WrapperData, Path extends string> {
} = {},
) {}
/** This should be used as the primary method in main since it allows the main to
* restart if the wrapper data changes
/**
* Returns the value of WrapperData at the provided path. Restart the service if the value changes
*/
const() {
return this.effects.getWrapperData<WrapperData, Path>({
@@ -23,8 +23,7 @@ export class GetWrapperData<WrapperData, Path extends string> {
})
}
/**
* Returns the wrapper data once and then never again
* Doesn't restart the server when the wrapper data changes
* Returns the value of WrapperData at the provided path. Does nothing if the value changes
*/
once() {
return this.effects.getWrapperData<WrapperData, Path>({
@@ -33,8 +32,9 @@ export class GetWrapperData<WrapperData, Path extends string> {
callback: () => {},
})
}
/**
* Keeps giving the latest wrapper data as it changes
* Watches the value of WrapperData at the provided path. Takes a custom callback function to run whenever the value changes
*/
async *watch() {
while (true) {

View File

@@ -1,6 +1,6 @@
{
"name": "start-sdk",
"version": "0.4.0-lib0.rc3",
"version": "0.4.0-lib0.rc4",
"description": "For making the patterns that are wanted in making services for the startOS.",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",