2024-07-30 23:33:33 +08:00
|
|
|
import type { SilverBulletHooks } from "../lib/manifest.ts";
|
2024-07-30 03:21:16 +08:00
|
|
|
import {
|
|
|
|
ensureAndLoadSettingsAndIndex,
|
|
|
|
updateObjectDecorators,
|
2024-08-02 22:47:36 +08:00
|
|
|
} from "../common/config.ts";
|
2024-02-09 04:00:45 +08:00
|
|
|
import { AssetBundlePlugSpacePrimitives } from "$common/spaces/asset_bundle_space_primitives.ts";
|
|
|
|
import { FilteredSpacePrimitives } from "$common/spaces/filtered_space_primitives.ts";
|
|
|
|
import { ReadOnlySpacePrimitives } from "$common/spaces/ro_space_primitives.ts";
|
2024-07-30 23:33:33 +08:00
|
|
|
import type { SpacePrimitives } from "$common/spaces/space_primitives.ts";
|
|
|
|
import type { AssetBundle } from "../lib/asset_bundle/bundle.ts";
|
2024-02-28 03:05:12 +08:00
|
|
|
import { EventHook } from "../common/hooks/event.ts";
|
2024-02-09 04:00:45 +08:00
|
|
|
import { DataStore } from "$lib/data/datastore.ts";
|
2024-07-30 23:33:33 +08:00
|
|
|
import type { KvPrimitives } from "$lib/data/kv_primitives.ts";
|
2024-02-09 04:00:45 +08:00
|
|
|
import { DataStoreMQ } from "$lib/data/mq.datastore.ts";
|
2024-07-30 23:33:33 +08:00
|
|
|
import type { System } from "$lib/plugos/system.ts";
|
2023-12-11 19:11:56 +08:00
|
|
|
import { JWTIssuer } from "./crypto.ts";
|
2024-03-16 22:29:24 +08:00
|
|
|
import { compile as gitIgnoreCompiler } from "gitignore-parser";
|
2023-12-10 20:23:42 +08:00
|
|
|
import { ServerSystem } from "./server_system.ts";
|
2024-01-27 00:05:10 +08:00
|
|
|
import { determineShellBackend, NotSupportedShell } from "./shell_backend.ts";
|
2024-07-30 23:33:33 +08:00
|
|
|
import type { ShellBackend } from "./shell_backend.ts";
|
2023-12-10 20:23:42 +08:00
|
|
|
import { determineStorageBackend } from "./storage_backend.ts";
|
2024-08-15 22:39:06 +08:00
|
|
|
import {
|
|
|
|
type Config,
|
|
|
|
type ConfigContainer,
|
|
|
|
defaultConfig,
|
|
|
|
} from "../type/config.ts";
|
2024-08-07 19:27:25 +08:00
|
|
|
import type { ServerOptions } from "./http_server.ts";
|
2024-11-15 23:50:50 +08:00
|
|
|
import type { AuthOptions } from "../cmd/server.ts";
|
2023-12-10 20:23:42 +08:00
|
|
|
|
2024-02-07 21:50:01 +08:00
|
|
|
// Equivalent of Client on the server
|
2024-08-02 22:47:36 +08:00
|
|
|
export class SpaceServer implements ConfigContainer {
|
2023-12-10 20:23:42 +08:00
|
|
|
public pagesPath: string;
|
2024-11-15 23:50:50 +08:00
|
|
|
auth?: AuthOptions;
|
2023-12-10 20:23:42 +08:00
|
|
|
hostname: string;
|
|
|
|
|
2024-08-02 22:47:36 +08:00
|
|
|
config: Config;
|
2023-12-14 00:52:56 +08:00
|
|
|
spacePrimitives!: SpacePrimitives;
|
2023-12-10 20:23:42 +08:00
|
|
|
|
2023-12-11 19:11:56 +08:00
|
|
|
jwtIssuer: JWTIssuer;
|
|
|
|
|
2023-12-10 20:23:42 +08:00
|
|
|
// Only set when syncOnly == false
|
2024-07-27 01:12:10 +08:00
|
|
|
serverSystem?: ServerSystem;
|
2023-12-10 20:23:42 +08:00
|
|
|
system?: System<SilverBulletHooks>;
|
2023-12-17 18:46:18 +08:00
|
|
|
syncOnly: boolean;
|
2024-01-27 00:05:10 +08:00
|
|
|
readOnly: boolean;
|
|
|
|
shellBackend: ShellBackend;
|
2024-02-06 23:51:04 +08:00
|
|
|
enableSpaceScript: boolean;
|
2023-12-10 20:23:42 +08:00
|
|
|
|
|
|
|
constructor(
|
2024-08-07 19:27:25 +08:00
|
|
|
options: ServerOptions,
|
2023-12-14 00:52:56 +08:00
|
|
|
private plugAssetBundle: AssetBundle,
|
|
|
|
private kvPrimitives: KvPrimitives,
|
2023-12-10 20:23:42 +08:00
|
|
|
) {
|
2024-08-07 19:27:25 +08:00
|
|
|
this.pagesPath = options.pagesPath;
|
|
|
|
this.hostname = options.hostname;
|
|
|
|
this.auth = options.auth;
|
|
|
|
this.syncOnly = options.syncOnly;
|
|
|
|
this.readOnly = options.readOnly;
|
2024-08-02 22:47:36 +08:00
|
|
|
this.config = defaultConfig;
|
2024-08-07 19:27:25 +08:00
|
|
|
this.enableSpaceScript = options.enableSpaceScript;
|
2024-02-06 23:51:04 +08:00
|
|
|
|
2023-12-14 00:52:56 +08:00
|
|
|
this.jwtIssuer = new JWTIssuer(kvPrimitives);
|
2024-01-27 00:05:10 +08:00
|
|
|
|
2024-08-07 19:27:25 +08:00
|
|
|
this.shellBackend = options.readOnly
|
2024-01-27 00:05:10 +08:00
|
|
|
? new NotSupportedShell() // No shell for read only mode
|
2024-08-07 19:27:25 +08:00
|
|
|
: determineShellBackend(options);
|
2023-12-14 00:52:56 +08:00
|
|
|
}
|
2023-12-10 20:23:42 +08:00
|
|
|
|
2023-12-14 00:52:56 +08:00
|
|
|
async init() {
|
2023-12-10 20:23:42 +08:00
|
|
|
let fileFilterFn: (s: string) => boolean = () => true;
|
|
|
|
|
|
|
|
this.spacePrimitives = new FilteredSpacePrimitives(
|
|
|
|
new AssetBundlePlugSpacePrimitives(
|
2023-12-14 00:52:56 +08:00
|
|
|
await determineStorageBackend(this.kvPrimitives, this.pagesPath),
|
|
|
|
this.plugAssetBundle,
|
2023-12-10 20:23:42 +08:00
|
|
|
),
|
|
|
|
(meta) => fileFilterFn(meta.name),
|
|
|
|
async () => {
|
2024-08-02 22:47:36 +08:00
|
|
|
await this.loadConfig();
|
|
|
|
if (typeof this.config?.spaceIgnore === "string") {
|
|
|
|
fileFilterFn = gitIgnoreCompiler(this.config.spaceIgnore).accepts;
|
2023-12-10 20:23:42 +08:00
|
|
|
} else {
|
|
|
|
fileFilterFn = () => true;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2024-01-27 00:05:10 +08:00
|
|
|
if (this.readOnly) {
|
|
|
|
this.spacePrimitives = new ReadOnlySpacePrimitives(this.spacePrimitives);
|
|
|
|
}
|
|
|
|
|
2024-02-07 21:50:01 +08:00
|
|
|
const ds = new DataStore(this.kvPrimitives);
|
|
|
|
const mq = new DataStoreMQ(ds);
|
|
|
|
|
|
|
|
const eventHook = new EventHook();
|
|
|
|
|
2023-12-10 20:23:42 +08:00
|
|
|
// system = undefined in databaseless mode (no PlugOS instance on the server and no DB)
|
2023-12-14 00:52:56 +08:00
|
|
|
if (!this.syncOnly) {
|
2023-12-10 20:23:42 +08:00
|
|
|
// Enable server-side processing
|
|
|
|
const serverSystem = new ServerSystem(
|
|
|
|
this.spacePrimitives,
|
2023-12-14 00:52:56 +08:00
|
|
|
this.kvPrimitives,
|
2023-12-17 22:25:44 +08:00
|
|
|
this.shellBackend,
|
2024-02-07 21:50:01 +08:00
|
|
|
mq,
|
|
|
|
ds,
|
|
|
|
eventHook,
|
2024-01-27 00:05:10 +08:00
|
|
|
this.readOnly,
|
2024-02-06 23:51:04 +08:00
|
|
|
this.enableSpaceScript,
|
2024-08-02 22:47:36 +08:00
|
|
|
this,
|
2023-12-10 20:23:42 +08:00
|
|
|
);
|
|
|
|
this.serverSystem = serverSystem;
|
|
|
|
}
|
|
|
|
|
2023-12-11 19:11:56 +08:00
|
|
|
if (this.auth) {
|
|
|
|
// Initialize JWT issuer
|
2023-12-14 00:52:56 +08:00
|
|
|
await this.jwtIssuer.init(
|
2024-11-15 23:50:50 +08:00
|
|
|
JSON.stringify({ auth: this.auth }),
|
2023-12-14 00:52:56 +08:00
|
|
|
);
|
2023-12-11 19:11:56 +08:00
|
|
|
}
|
|
|
|
|
2023-12-10 20:23:42 +08:00
|
|
|
if (this.serverSystem) {
|
|
|
|
await this.serverSystem.init();
|
|
|
|
this.system = this.serverSystem.system;
|
2023-12-14 00:52:56 +08:00
|
|
|
// Swap in the space primitives from the server system
|
|
|
|
this.spacePrimitives = this.serverSystem.spacePrimitives;
|
2023-12-10 20:23:42 +08:00
|
|
|
}
|
|
|
|
|
2024-08-02 22:47:36 +08:00
|
|
|
await this.loadConfig();
|
2023-12-10 20:23:42 +08:00
|
|
|
console.log("Booted server with hostname", this.hostname);
|
|
|
|
}
|
|
|
|
|
2024-08-02 22:47:36 +08:00
|
|
|
async loadConfig() {
|
|
|
|
this.config = await ensureAndLoadSettingsAndIndex(
|
|
|
|
this.spacePrimitives,
|
|
|
|
this.system,
|
|
|
|
);
|
2024-07-30 03:21:16 +08:00
|
|
|
|
|
|
|
if (this.serverSystem) {
|
2024-08-02 22:47:36 +08:00
|
|
|
updateObjectDecorators(this.config, this.serverSystem.ds);
|
2024-08-04 02:59:53 +08:00
|
|
|
this.serverSystem.eventHook.dispatchEvent("config:loaded", this.config);
|
2024-07-30 03:21:16 +08:00
|
|
|
}
|
2023-12-10 20:23:42 +08:00
|
|
|
}
|
|
|
|
}
|