@phreshos/core 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +19 -0
- package/README.md +252 -75
- package/dist/askable.d.ts +5 -1
- package/dist/channel.d.ts +3 -2
- package/dist/client.d.ts +5 -5
- package/dist/color.d.ts +10 -0
- package/dist/color.js +14 -0
- package/dist/config.d.ts +22 -11
- package/dist/config.js +0 -6
- package/dist/endpoint.d.ts +6 -5
- package/dist/launch.d.ts +12 -2
- package/dist/main.d.ts +11 -4
- package/dist/main.js +8 -1
- package/dist/outcome.d.ts +4 -0
- package/dist/permissions.d.ts +34 -0
- package/dist/permissions.js +6 -0
- package/dist/process.d.ts +5 -9
- package/dist/program.d.ts +24 -14
- package/dist/publishable.d.ts +5 -1
- package/dist/scale.d.ts +12 -0
- package/dist/scale.js +29 -0
- package/dist/server.d.ts +4 -4
- package/dist/sql.d.ts +7 -0
- package/dist/storage.d.ts +10 -0
- package/dist/subscribable.d.ts +32 -3
- package/dist/theme.d.ts +132 -0
- package/dist/theme.js +34 -0
- package/dist/timeout.d.ts +5 -0
- package/dist/timeout.js +0 -0
- package/dist/value.d.ts +17 -0
- package/dist/value.js +118 -0
- package/dist/wallpaper.d.ts +30 -0
- package/dist/wallpaper.js +0 -0
- package/dist/window.d.ts +41 -12
- package/dist/window.js +0 -4
- package/package.json +35 -9
- package/source/askable.ts +0 -26
- package/source/channel.ts +0 -28
- package/source/client.ts +0 -29
- package/source/config.ts +0 -104
- package/source/endpoint.ts +0 -95
- package/source/launch.ts +0 -43
- package/source/main.ts +0 -65
- package/source/outcome.ts +0 -4
- package/source/process.ts +0 -77
- package/source/program.ts +0 -130
- package/source/publishable.ts +0 -33
- package/source/served-file.ts +0 -14
- package/source/server.ts +0 -58
- package/source/sql.ts +0 -36
- package/source/storage.ts +0 -66
- package/source/subscribable.ts +0 -94
- package/source/window.ts +0 -82
package/dist/value.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reduces a strict linear expression into `span * relative + pixels`.
|
|
3
|
+
*
|
|
4
|
+
* Numbers are absolute values. Percentages and `n/d` fractions are relative
|
|
5
|
+
* values. Addition and subtraction combine terms; multiplication and division
|
|
6
|
+
* scale the preceding term by a number. No arbitrary code or CSS is accepted.
|
|
7
|
+
*/
|
|
8
|
+
export function parseRelativeValue(input) {
|
|
9
|
+
if (typeof input === "number")
|
|
10
|
+
return Number.isFinite(input) ? { relative: 0, pixels: clean(input) } : null;
|
|
11
|
+
if (typeof input !== "string" || input.trim().length === 0)
|
|
12
|
+
return null;
|
|
13
|
+
return new Reader(input).parse();
|
|
14
|
+
}
|
|
15
|
+
/** Returns whether a value belongs to the linear relative-value grammar. */
|
|
16
|
+
export function isRelativeValue(value) {
|
|
17
|
+
return parseRelativeValue(value) !== null;
|
|
18
|
+
}
|
|
19
|
+
class Reader {
|
|
20
|
+
position = 0;
|
|
21
|
+
source;
|
|
22
|
+
constructor(source) {
|
|
23
|
+
this.source = source;
|
|
24
|
+
}
|
|
25
|
+
parse() {
|
|
26
|
+
const value = { relative: 0, pixels: 0 };
|
|
27
|
+
let direction = this.sign();
|
|
28
|
+
while (this.position < this.source.length) {
|
|
29
|
+
const term = this.term();
|
|
30
|
+
if (!term)
|
|
31
|
+
return null;
|
|
32
|
+
value.relative += term.relative * direction;
|
|
33
|
+
value.pixels += term.pixels * direction;
|
|
34
|
+
if (!finite(value))
|
|
35
|
+
return null;
|
|
36
|
+
this.space();
|
|
37
|
+
if (this.position === this.source.length)
|
|
38
|
+
return { relative: clean(value.relative), pixels: clean(value.pixels) };
|
|
39
|
+
const operator = this.source[this.position];
|
|
40
|
+
if (operator !== "+" && operator !== "-")
|
|
41
|
+
return null;
|
|
42
|
+
this.position += 1;
|
|
43
|
+
direction = (operator === "+" ? 1 : -1) * this.sign();
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
term() {
|
|
48
|
+
const value = this.measurement();
|
|
49
|
+
if (!value)
|
|
50
|
+
return null;
|
|
51
|
+
while (true) {
|
|
52
|
+
this.space();
|
|
53
|
+
const operator = this.source[this.position];
|
|
54
|
+
if (operator !== "*" && operator !== "/")
|
|
55
|
+
return value;
|
|
56
|
+
this.position += 1;
|
|
57
|
+
const scalar = this.scalar();
|
|
58
|
+
if (scalar === null || operator === "/" && scalar === 0)
|
|
59
|
+
return null;
|
|
60
|
+
const factor = operator === "*" ? scalar : 1 / scalar;
|
|
61
|
+
value.relative *= factor;
|
|
62
|
+
value.pixels *= factor;
|
|
63
|
+
if (!finite(value))
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
measurement() {
|
|
68
|
+
this.space();
|
|
69
|
+
const remainder = this.source.slice(this.position);
|
|
70
|
+
const fraction = remainder.match(/^(\d+(?:\.\d+)?|\.\d+)\s*\/\s*(\d+(?:\.\d+)?|\.\d+)(?![\d.])/);
|
|
71
|
+
if (fraction) {
|
|
72
|
+
const denominator = Number(fraction[2]);
|
|
73
|
+
if (!denominator)
|
|
74
|
+
return null;
|
|
75
|
+
this.position += fraction[0].length;
|
|
76
|
+
return { relative: Number(fraction[1]) / denominator, pixels: 0 };
|
|
77
|
+
}
|
|
78
|
+
const percentage = remainder.match(/^(\d+(?:\.\d+)?|\.\d+)\s*%/);
|
|
79
|
+
if (percentage) {
|
|
80
|
+
this.position += percentage[0].length;
|
|
81
|
+
return { relative: Number(percentage[1]) / 100, pixels: 0 };
|
|
82
|
+
}
|
|
83
|
+
const number = this.number();
|
|
84
|
+
return number === null ? null : { relative: 0, pixels: number };
|
|
85
|
+
}
|
|
86
|
+
scalar() {
|
|
87
|
+
const direction = this.sign();
|
|
88
|
+
const value = this.number();
|
|
89
|
+
return value === null ? null : value * direction;
|
|
90
|
+
}
|
|
91
|
+
number() {
|
|
92
|
+
this.space();
|
|
93
|
+
const number = this.source.slice(this.position).match(/^(\d+(?:\.\d+)?|\.\d+)/)?.[0];
|
|
94
|
+
if (!number)
|
|
95
|
+
return null;
|
|
96
|
+
this.position += number.length;
|
|
97
|
+
return Number(number);
|
|
98
|
+
}
|
|
99
|
+
sign() {
|
|
100
|
+
this.space();
|
|
101
|
+
const sign = this.source[this.position];
|
|
102
|
+
if (sign !== "+" && sign !== "-")
|
|
103
|
+
return 1;
|
|
104
|
+
this.position += 1;
|
|
105
|
+
this.space();
|
|
106
|
+
return sign === "-" ? -1 : 1;
|
|
107
|
+
}
|
|
108
|
+
space() {
|
|
109
|
+
while (/\s/.test(this.source[this.position] ?? ""))
|
|
110
|
+
this.position += 1;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function finite(value) {
|
|
114
|
+
return Number.isFinite(value.relative) && Number.isFinite(value.pixels);
|
|
115
|
+
}
|
|
116
|
+
function clean(value) {
|
|
117
|
+
return Object.is(value, -0) ? 0 : value;
|
|
118
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Program } from "./program.js";
|
|
2
|
+
import type { Launch, LaunchClient } from "./launch.js";
|
|
3
|
+
/** The only Process settings configurable for a desktop Program wallpaper. */
|
|
4
|
+
export type WallpaperLaunch = Readonly<{
|
|
5
|
+
/** Optional meaningful name unique among the Program's live Processes. */
|
|
6
|
+
name?: string;
|
|
7
|
+
/** Whether to include the Program's declared Server. */
|
|
8
|
+
server?: boolean;
|
|
9
|
+
/** Optional initial page beneath the Client's declared location scope. */
|
|
10
|
+
client?: Pick<LaunchClient, "location">;
|
|
11
|
+
/** Immutable text values available to both endpoints of this Process. */
|
|
12
|
+
options?: Launch["options"];
|
|
13
|
+
}>;
|
|
14
|
+
/** File-backed wallpaper assigned to one system surface. */
|
|
15
|
+
export interface FileWallpaper {
|
|
16
|
+
/** Selects one file previously created through `host.serve()`. */
|
|
17
|
+
set(file: string): Promise<void>;
|
|
18
|
+
/** Removes the customization so the bundled wallpaper is used. */
|
|
19
|
+
remove(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
/** Desktop wallpaper, backed by either a served file or a Program. */
|
|
22
|
+
export interface DesktopWallpaper extends FileWallpaper {
|
|
23
|
+
/**
|
|
24
|
+
* Selects a Program as the desktop wallpaper.
|
|
25
|
+
*
|
|
26
|
+
* The Program must declare a Client. Its Client is always started and its
|
|
27
|
+
* Window becomes a protected wallpaper representation.
|
|
28
|
+
*/
|
|
29
|
+
setProgram(program: Program, launch?: WallpaperLaunch): Promise<void>;
|
|
30
|
+
}
|
|
File without changes
|
package/dist/window.d.ts
CHANGED
|
@@ -1,12 +1,44 @@
|
|
|
1
|
-
import type { Client } from "./client.js";
|
|
2
1
|
import type { Layer, Position, Size } from "./launch.js";
|
|
2
|
+
import type { ScaleLevel } from "./scale.js";
|
|
3
3
|
import type { Subscribable } from "./subscribable.js";
|
|
4
|
+
/** The authoritative runtime layer occupied by a Window. */
|
|
5
|
+
export type WindowLayer = Layer | "wallpaper";
|
|
6
|
+
/** Stable easing accepted by a Window Surface transaction. */
|
|
7
|
+
export type WindowSurfaceEasing = "linear" | "ease" | "ease-in" | "ease-out" | "ease-in-out" | readonly [number, number, number, number];
|
|
8
|
+
/** Motion applied by a desktop when one authoritative Surface target replaces another. */
|
|
9
|
+
export type WindowSurfaceTransaction = Readonly<{
|
|
10
|
+
/** Duration in milliseconds. Omission uses the system duration. */
|
|
11
|
+
duration?: number;
|
|
12
|
+
/** Timing curve. Omission uses the system curve. */
|
|
13
|
+
easing?: WindowSurfaceEasing;
|
|
14
|
+
}>;
|
|
15
|
+
/** Authoritative target settings for one Window's optional host Surface. */
|
|
16
|
+
export type WindowSurfaceSettings = Readonly<{
|
|
17
|
+
/** Whole-Surface opacity from zero through one. Omission means one. */
|
|
18
|
+
opacity?: number;
|
|
19
|
+
/** A Theme-derived level, CSS pixels, or maximum proportional rounding. Omission means zero. */
|
|
20
|
+
radius?: ScaleLevel | number | "full";
|
|
21
|
+
/** Optional motion from the currently rendered values to this target. */
|
|
22
|
+
transaction?: WindowSurfaceTransaction;
|
|
23
|
+
}>;
|
|
24
|
+
/** Optional host-rendered material owned by one authoritative Window. */
|
|
25
|
+
export interface WindowSurface {
|
|
26
|
+
/** Creates or replaces the authoritative target. Omission creates the default Surface. */
|
|
27
|
+
set(settings?: WindowSurfaceSettings): Promise<void>;
|
|
28
|
+
/** Immediately removes the authoritative Surface. */
|
|
29
|
+
remove(): Promise<void>;
|
|
30
|
+
}
|
|
4
31
|
/** Events emitted when authoritative Window state changes. */
|
|
5
32
|
export type WindowEvents = {
|
|
33
|
+
/** The authoritative top-left position changed. */
|
|
6
34
|
move: Position;
|
|
35
|
+
/** The authoritative width or height changed. */
|
|
7
36
|
resize: Size;
|
|
37
|
+
/** The authoritative minimized state changed. */
|
|
8
38
|
minimize: boolean;
|
|
39
|
+
/** The authoritative title changed. */
|
|
9
40
|
changeTitle: string;
|
|
41
|
+
/** Whether this Window became or ceased to be frontmost in its layer. */
|
|
10
42
|
front: boolean;
|
|
11
43
|
};
|
|
12
44
|
/** Current authoritative Window state. */
|
|
@@ -21,18 +53,15 @@ export type WindowState = Readonly<{
|
|
|
21
53
|
minimized: boolean;
|
|
22
54
|
/** Whether the Window is frontmost in its layer. */
|
|
23
55
|
front: boolean;
|
|
24
|
-
/**
|
|
25
|
-
layer:
|
|
56
|
+
/** Authoritative desktop layer containing the Window. */
|
|
57
|
+
layer: WindowLayer;
|
|
26
58
|
/** Current page beneath the declared Client location. */
|
|
27
59
|
location: string;
|
|
28
60
|
}>;
|
|
29
|
-
/**
|
|
30
|
-
export
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
export interface Window<Events extends object = {}> extends Subscribable<WindowEvents & Events, never> {
|
|
34
|
-
/** Returns the Client that owns this Window. */
|
|
35
|
-
client(): Client;
|
|
61
|
+
/** Presentation capability owned by one Client handle. */
|
|
62
|
+
export interface Window extends Subscribable<WindowEvents, never> {
|
|
63
|
+
/** Authoritative host-rendered material associated with this Window. */
|
|
64
|
+
readonly surface: WindowSurface;
|
|
36
65
|
/** Returns the current title. */
|
|
37
66
|
title(): Promise<string>;
|
|
38
67
|
/** Returns the current top-left position. */
|
|
@@ -43,8 +72,8 @@ export interface Window<Events extends object = {}> extends Subscribable<WindowE
|
|
|
43
72
|
minimized(): Promise<boolean>;
|
|
44
73
|
/** Returns whether the Window is frontmost in its layer. */
|
|
45
74
|
front(): Promise<boolean>;
|
|
46
|
-
/** Returns the
|
|
47
|
-
layer(): Promise<
|
|
75
|
+
/** Returns the authoritative desktop layer containing the Window. */
|
|
76
|
+
layer(): Promise<WindowLayer>;
|
|
48
77
|
/** Returns the current page rooted beneath the declared Client location. */
|
|
49
78
|
location(): Promise<string>;
|
|
50
79
|
/** Moves the authoritative Window. */
|
package/dist/window.js
CHANGED
package/package.json
CHANGED
|
@@ -1,27 +1,53 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phreshos/core",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Environment-neutral contracts and domain objects for PhreshOS Programs.",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
6
7
|
"main": "dist/main.js",
|
|
7
|
-
"types": "
|
|
8
|
+
"types": "dist/main.d.ts",
|
|
8
9
|
"exports": {
|
|
9
10
|
".": {
|
|
10
|
-
"types": "./
|
|
11
|
+
"types": "./dist/main.d.ts",
|
|
11
12
|
"default": "./dist/main.js"
|
|
12
13
|
}
|
|
13
14
|
},
|
|
14
15
|
"files": [
|
|
15
16
|
"dist",
|
|
16
|
-
"
|
|
17
|
+
"LICENSE",
|
|
17
18
|
"README.md"
|
|
18
19
|
],
|
|
20
|
+
"author": "Zohayr SLILEH",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/PhreshOS/core.git"
|
|
25
|
+
},
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/PhreshOS/core/issues"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://github.com/PhreshOS/core#readme",
|
|
30
|
+
"keywords": [
|
|
31
|
+
"phreshos",
|
|
32
|
+
"sdk",
|
|
33
|
+
"typescript"
|
|
34
|
+
],
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public",
|
|
37
|
+
"provenance": true
|
|
38
|
+
},
|
|
39
|
+
"packageManager": "bun@1.3.14",
|
|
19
40
|
"scripts": {
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
41
|
+
"clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
|
|
42
|
+
"check": "tsc --noEmit && tsc -p tsconfig.test.json",
|
|
43
|
+
"test": "vitest run",
|
|
44
|
+
"build": "node --run clean && tsc --noEmit false --outDir dist --rootDir source",
|
|
45
|
+
"verify:package": "node scripts/verify-package.mjs",
|
|
46
|
+
"verify": "node --run check && node --run test && node --run build && node --run verify:package",
|
|
47
|
+
"prepack": "node --run test && node --run build"
|
|
23
48
|
},
|
|
24
49
|
"devDependencies": {
|
|
25
|
-
"typescript": "^6.0.3"
|
|
50
|
+
"typescript": "^6.0.3",
|
|
51
|
+
"vitest": "^4.1.1"
|
|
26
52
|
}
|
|
27
53
|
}
|
package/source/askable.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type { Publishable } from "./publishable.js"
|
|
2
|
-
|
|
3
|
-
/** An immutable Askable view using one caller-selected deadline. */
|
|
4
|
-
export interface TimedAskable {
|
|
5
|
-
/** Sends one question and waits within the selected deadline. */
|
|
6
|
-
ask<Answer = unknown, Payload = unknown>(event: string, payload: Payload): Promise<Answer>
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
/** A publishing target that can also receive a question and return an answer. */
|
|
10
|
-
export interface Askable<Events extends object = {}, Fallback = unknown>
|
|
11
|
-
extends Publishable<Events, Fallback> {
|
|
12
|
-
/**
|
|
13
|
-
* Sends one question payload to this target and waits for its answer.
|
|
14
|
-
*
|
|
15
|
-
* The SDK uses a ten-second deadline by default. It sends the question only
|
|
16
|
-
* after the current Server incarnation becomes ready. The operation rejects
|
|
17
|
-
* immediately when that Server is absent, and also rejects if the incarnation
|
|
18
|
-
* stops before readiness or before answering. One SDK deadline covers both
|
|
19
|
-
* readiness and the answer. The boundary cannot infer whether an answerer
|
|
20
|
-
* exists, so a ready unanswered question waits for that deadline.
|
|
21
|
-
*/
|
|
22
|
-
ask<Answer = unknown, Payload = unknown>(event: string, payload: Payload): Promise<Answer>
|
|
23
|
-
|
|
24
|
-
/** Returns an immutable view whose `ask()` uses this deadline in milliseconds. */
|
|
25
|
-
timeout(milliseconds: number): TimedAskable
|
|
26
|
-
}
|
package/source/channel.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { Endpoint } from "./endpoint.js"
|
|
2
|
-
import type { Captures, Subscribable } from "./subscribable.js"
|
|
3
|
-
|
|
4
|
-
/** One application value arriving through the current Endpoint's Channel. */
|
|
5
|
-
export type ChannelMessage<Payload = unknown, From = Endpoint> = Readonly<{
|
|
6
|
-
/** Endpoint that sent the message, or `null` when its identity is outside this boundary. */
|
|
7
|
-
from: From
|
|
8
|
-
|
|
9
|
-
/** Single value supplied by the publisher. */
|
|
10
|
-
payload: Payload
|
|
11
|
-
}>
|
|
12
|
-
|
|
13
|
-
/** Applies the sender envelope to every application event accepted here. */
|
|
14
|
-
export type ChannelEvents<Events extends object, From = Endpoint> = {
|
|
15
|
-
readonly [Event in keyof Events]: ChannelMessage<Events[Event], From>
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
type ChannelFallback<Events extends object, From> = keyof Events extends never
|
|
19
|
-
? ChannelMessage<unknown, From>
|
|
20
|
-
: never
|
|
21
|
-
|
|
22
|
-
/** Every application event observable through a Channel. */
|
|
23
|
-
export type ChannelCapture<Events extends object = {}, From = Endpoint> =
|
|
24
|
-
Captures<ChannelEvents<Events, From>, ChannelFallback<Events, From>>
|
|
25
|
-
|
|
26
|
-
/** Events explicitly accepted by the current Endpoint. */
|
|
27
|
-
export interface Channel<Events extends object = {}, From = Endpoint>
|
|
28
|
-
extends Subscribable<ChannelEvents<Events, From>, ChannelFallback<Events, From>> {}
|
package/source/client.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { Endpoint, type EndpointTraffic } from "./endpoint.js"
|
|
2
|
-
import type { LaunchClient } from "./launch.js"
|
|
3
|
-
import type { Server } from "./server.js"
|
|
4
|
-
import type { Window } from "./window.js"
|
|
5
|
-
|
|
6
|
-
/** Broad communication originating from one Client. */
|
|
7
|
-
export interface ClientTraffic<
|
|
8
|
-
Events extends object = {},
|
|
9
|
-
To = Endpoint,
|
|
10
|
-
AskTo = Server
|
|
11
|
-
> extends EndpointTraffic<Events, To, AskTo> {}
|
|
12
|
-
|
|
13
|
-
/** The client Endpoint of a Process. */
|
|
14
|
-
export class Client<Events extends object = {}> extends Endpoint<Events> {
|
|
15
|
-
public constructor() {
|
|
16
|
-
super()
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface Client<Events extends object = {}> {
|
|
21
|
-
/** Broad communication originating from this Client. */
|
|
22
|
-
readonly traffic: ClientTraffic<Events>
|
|
23
|
-
|
|
24
|
-
/** Starts a fresh Client and Window using optional Process-local overrides. */
|
|
25
|
-
start(overrides?: LaunchClient): Promise<void>
|
|
26
|
-
|
|
27
|
-
/** Returns the Window owned by this live Client. */
|
|
28
|
-
window(): Promise<Window>
|
|
29
|
-
}
|
package/source/config.ts
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import type { Layer, Position, Size } from "./launch.js"
|
|
2
|
-
|
|
3
|
-
/** Development settings for a Program's Server. */
|
|
4
|
-
export type ServerDevelopment = Readonly<{
|
|
5
|
-
/** Command that starts the development Server from the project directory. */
|
|
6
|
-
startCommand: string
|
|
7
|
-
}>
|
|
8
|
-
|
|
9
|
-
/** Development settings for a Program's Client. */
|
|
10
|
-
export type ClientDevelopment = Readonly<{
|
|
11
|
-
/** HTTP(S) URL served by the Client's development server. */
|
|
12
|
-
url: string
|
|
13
|
-
|
|
14
|
-
/** Optional command that starts the Client's development server. */
|
|
15
|
-
startCommand?: string
|
|
16
|
-
}>
|
|
17
|
-
|
|
18
|
-
/** Authoring declaration for a Program's Server. */
|
|
19
|
-
export type ServerConfig = Readonly<{
|
|
20
|
-
/** Production directory containing the Server. */
|
|
21
|
-
location: string
|
|
22
|
-
|
|
23
|
-
/** Whether a default Process starts its Server. Defaults to `true`. */
|
|
24
|
-
start?: boolean
|
|
25
|
-
|
|
26
|
-
/** Optional preparation command run from {@link location} while installing. */
|
|
27
|
-
installCommand?: string
|
|
28
|
-
|
|
29
|
-
/** Command that starts the production Server from {@link location}. */
|
|
30
|
-
startCommand: string
|
|
31
|
-
|
|
32
|
-
/** Settings used only by the development command. */
|
|
33
|
-
development?: ServerDevelopment
|
|
34
|
-
}>
|
|
35
|
-
|
|
36
|
-
/** Authoring declaration for a Program's Client and initial Window. */
|
|
37
|
-
export type ClientConfig = Readonly<{
|
|
38
|
-
/** Production directory containing the Client and its `index.html`. */
|
|
39
|
-
location: string
|
|
40
|
-
|
|
41
|
-
/** Whether a default Process starts its Client. Defaults to `true`. */
|
|
42
|
-
start?: boolean
|
|
43
|
-
|
|
44
|
-
/** Initial Window title. Defaults to the Program name. */
|
|
45
|
-
title?: string
|
|
46
|
-
|
|
47
|
-
/** Initial Window size. */
|
|
48
|
-
size?: Size
|
|
49
|
-
|
|
50
|
-
/** Initial Window position. */
|
|
51
|
-
position?: Position
|
|
52
|
-
|
|
53
|
-
/** Structurally isolated desktop layer containing the Window. */
|
|
54
|
-
layer?: Layer
|
|
55
|
-
|
|
56
|
-
/** Whether the Window initially opens minimized. */
|
|
57
|
-
minimize?: boolean
|
|
58
|
-
|
|
59
|
-
/** Settings used only by the development command. */
|
|
60
|
-
development?: ClientDevelopment
|
|
61
|
-
}>
|
|
62
|
-
|
|
63
|
-
type Description = Readonly<{
|
|
64
|
-
/** Stable public identity written in kebab-case. */
|
|
65
|
-
identity: string
|
|
66
|
-
|
|
67
|
-
/** Human-readable Program name. Defaults to {@link identity}. */
|
|
68
|
-
name?: string
|
|
69
|
-
|
|
70
|
-
/** Program version shown to people and included in packages. */
|
|
71
|
-
version?: string
|
|
72
|
-
|
|
73
|
-
/** Short human-readable explanation of what the Program does. */
|
|
74
|
-
description?: string
|
|
75
|
-
|
|
76
|
-
/** Markdown file that officially introduces the Program's API. */
|
|
77
|
-
apiDocs?: string
|
|
78
|
-
|
|
79
|
-
/** Directory containing the Program's sized icons. */
|
|
80
|
-
icons?: string
|
|
81
|
-
|
|
82
|
-
/** Command run before production start, installation, and packaging. */
|
|
83
|
-
buildCommand?: string
|
|
84
|
-
}>
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* The authoring description read from `phresh.config.ts`.
|
|
88
|
-
*
|
|
89
|
-
* A Program must declare a Server, a Client, or both.
|
|
90
|
-
*/
|
|
91
|
-
export type Config = Description & (
|
|
92
|
-
| Readonly<{ server: ServerConfig, client?: ClientConfig }>
|
|
93
|
-
| Readonly<{ server?: ServerConfig, client: ClientConfig }>
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Defines a Program authoring description with contextual typing.
|
|
98
|
-
*
|
|
99
|
-
* This helper performs no work and returns the supplied description unchanged.
|
|
100
|
-
* The CLI validates and derives it for development, production, or packaging.
|
|
101
|
-
*/
|
|
102
|
-
export function defineConfig<const Description extends Config>(config: Description): Description {
|
|
103
|
-
return config
|
|
104
|
-
}
|
package/source/endpoint.ts
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import type { Process } from "./process.js"
|
|
2
|
-
import type { Publishable } from "./publishable.js"
|
|
3
|
-
import type { Server } from "./server.js"
|
|
4
|
-
import type { Captures, Cleanup, Subscribable } from "./subscribable.js"
|
|
5
|
-
|
|
6
|
-
/** One application value observed in traffic originating from an Endpoint. */
|
|
7
|
-
export type TrafficMessage<Payload = unknown, To = Endpoint> = Readonly<{
|
|
8
|
-
/** Destination Endpoint, or `null` when its identity is outside this boundary. */
|
|
9
|
-
to: To
|
|
10
|
-
|
|
11
|
-
/** Single value supplied by the publisher. */
|
|
12
|
-
payload: Payload
|
|
13
|
-
}>
|
|
14
|
-
|
|
15
|
-
/** Applies destination metadata to every observed ordinary event. */
|
|
16
|
-
export type TrafficEvents<Events extends object, To = Endpoint> = {
|
|
17
|
-
readonly [Event in keyof Events]: TrafficMessage<Events[Event], To>
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
type TrafficFallback<Events extends object, To> = keyof Events extends never
|
|
21
|
-
? TrafficMessage<unknown, To>
|
|
22
|
-
: never
|
|
23
|
-
|
|
24
|
-
/** One question sent by this Endpoint to a Server. */
|
|
25
|
-
export type AskMessage<Payload = unknown, To = Server> = Readonly<{
|
|
26
|
-
/** Destination Server, or `null` when its identity is outside this boundary. */
|
|
27
|
-
to: To
|
|
28
|
-
|
|
29
|
-
/** Single question value supplied by the asker. */
|
|
30
|
-
payload: Payload
|
|
31
|
-
}>
|
|
32
|
-
|
|
33
|
-
/** One observed question sent by this Endpoint. */
|
|
34
|
-
export type AskCapture<Payload = unknown, To = Server> = Readonly<{
|
|
35
|
-
/** Event addressed by the question. */
|
|
36
|
-
event: string
|
|
37
|
-
|
|
38
|
-
/** Correlation identity shared with the eventual answer. */
|
|
39
|
-
questionId: string
|
|
40
|
-
|
|
41
|
-
/** Question destination and payload. */
|
|
42
|
-
message: AskMessage<Payload, To>
|
|
43
|
-
}>
|
|
44
|
-
|
|
45
|
-
/** A callback that observes questions sent by this Endpoint. */
|
|
46
|
-
export type AskObserver<Payload = unknown, To = Server> = (capture: AskCapture<Payload, To>) => unknown
|
|
47
|
-
|
|
48
|
-
/** Every ordinary publication observable in traffic from one Endpoint. */
|
|
49
|
-
export type TrafficCapture<Events extends object = {}, To = Endpoint> =
|
|
50
|
-
Captures<TrafficEvents<Events, To>, TrafficFallback<Events, To>>
|
|
51
|
-
|
|
52
|
-
/** Broad communication originating from one Endpoint, regardless of destination. */
|
|
53
|
-
export interface EndpointTraffic<
|
|
54
|
-
Events extends object = {},
|
|
55
|
-
To = Endpoint,
|
|
56
|
-
AskTo = Server
|
|
57
|
-
> extends Subscribable<TrafficEvents<Events, To>, TrafficFallback<Events, To>> {
|
|
58
|
-
/** Observes questions originating from this Endpoint. */
|
|
59
|
-
observeAsks<Payload = unknown>(observer: AskObserver<Payload, AskTo>): Cleanup
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** The shared Process endpoint represented by Server and Client. */
|
|
63
|
-
export class Endpoint<Events extends object = {}> {
|
|
64
|
-
public constructor() {}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export interface Endpoint<Events extends object = {}>
|
|
68
|
-
extends Publishable {
|
|
69
|
-
/** Broad communication originating from this Endpoint. */
|
|
70
|
-
readonly traffic: EndpointTraffic<Events>
|
|
71
|
-
|
|
72
|
-
/** Returns the Process that owns this Endpoint. */
|
|
73
|
-
process(): Process
|
|
74
|
-
|
|
75
|
-
/** Returns whether this Endpoint currently has a live incarnation. */
|
|
76
|
-
exists(): Promise<boolean>
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Starts a fresh incarnation without waiting for Server readiness.
|
|
80
|
-
*
|
|
81
|
-
* Rejects when the Process is gone or inaccessible, the Program did not
|
|
82
|
-
* declare this endpoint kind, the Endpoint is already starting or live, or
|
|
83
|
-
* creation fails.
|
|
84
|
-
*/
|
|
85
|
-
start(): Promise<void>
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Stops the current incarnation and destroys its boundary-owned resources.
|
|
89
|
-
*
|
|
90
|
-
* Rejects when the Process is gone or inaccessible, the Endpoint is already
|
|
91
|
-
* stopping or absent, this is the Process's final live Endpoint, or stopping
|
|
92
|
-
* fails. Stopping never exits the Process implicitly.
|
|
93
|
-
*/
|
|
94
|
-
stop(): Promise<void>
|
|
95
|
-
}
|
package/source/launch.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/** A pixel count or a relative linear expression. */
|
|
2
|
-
export type Value = number | string
|
|
3
|
-
|
|
4
|
-
/** A Window's top-left position. */
|
|
5
|
-
export type Position = Readonly<{
|
|
6
|
-
/** Horizontal position. */
|
|
7
|
-
x: Value
|
|
8
|
-
|
|
9
|
-
/** Vertical position. */
|
|
10
|
-
y: Value
|
|
11
|
-
}>
|
|
12
|
-
|
|
13
|
-
/** A Window's width and height. */
|
|
14
|
-
export type Size = Readonly<{
|
|
15
|
-
/** Window width. */
|
|
16
|
-
width: Value
|
|
17
|
-
|
|
18
|
-
/** Window height. */
|
|
19
|
-
height: Value
|
|
20
|
-
}>
|
|
21
|
-
|
|
22
|
-
/** A structurally isolated desktop layer. */
|
|
23
|
-
export type Layer = "window" | "under" | "over"
|
|
24
|
-
|
|
25
|
-
/** Every structurally isolated desktop layer. */
|
|
26
|
-
export const layers: readonly Layer[] = ["window", "under", "over"]
|
|
27
|
-
|
|
28
|
-
/** Per-Process overrides used when starting a Client and its Window. */
|
|
29
|
-
export type LaunchClient = Readonly<{
|
|
30
|
-
size?: Size
|
|
31
|
-
position?: Position
|
|
32
|
-
layer?: Layer
|
|
33
|
-
location?: string
|
|
34
|
-
minimize?: boolean
|
|
35
|
-
}>
|
|
36
|
-
|
|
37
|
-
/** Initial endpoint selection and immutable options for one Process. */
|
|
38
|
-
export type Launch = Readonly<{
|
|
39
|
-
name?: string
|
|
40
|
-
server?: boolean
|
|
41
|
-
client?: boolean | LaunchClient
|
|
42
|
-
options?: Readonly<Record<string, string>>
|
|
43
|
-
}>
|