@phreshos/core 0.1.0
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/README.md +159 -0
- package/dist/askable.d.ts +22 -0
- package/dist/askable.js +0 -0
- package/dist/channel.d.ts +20 -0
- package/dist/channel.js +0 -0
- package/dist/client.d.ts +19 -0
- package/dist/client.js +7 -0
- package/dist/config.d.ts +81 -0
- package/dist/config.js +9 -0
- package/dist/endpoint.d.ts +70 -0
- package/dist/endpoint.js +4 -0
- package/dist/launch.d.ts +35 -0
- package/dist/launch.js +2 -0
- package/dist/main.d.ts +16 -0
- package/dist/main.js +16 -0
- package/dist/outcome.d.ts +8 -0
- package/dist/outcome.js +0 -0
- package/dist/process.d.ts +58 -0
- package/dist/process.js +4 -0
- package/dist/program.d.ts +96 -0
- package/dist/program.js +4 -0
- package/dist/publishable.d.ts +21 -0
- package/dist/publishable.js +0 -0
- package/dist/served-file.d.ts +11 -0
- package/dist/served-file.js +0 -0
- package/dist/server.d.ts +42 -0
- package/dist/server.js +7 -0
- package/dist/sql.d.ts +17 -0
- package/dist/sql.js +0 -0
- package/dist/storage.d.ts +49 -0
- package/dist/storage.js +0 -0
- package/dist/subscribable.d.ts +72 -0
- package/dist/subscribable.js +0 -0
- package/dist/window.d.ts +60 -0
- package/dist/window.js +4 -0
- package/package.json +27 -0
- package/source/askable.ts +26 -0
- package/source/channel.ts +28 -0
- package/source/client.ts +29 -0
- package/source/config.ts +104 -0
- package/source/endpoint.ts +95 -0
- package/source/launch.ts +43 -0
- package/source/main.ts +65 -0
- package/source/outcome.ts +4 -0
- package/source/process.ts +77 -0
- package/source/program.ts +130 -0
- package/source/publishable.ts +33 -0
- package/source/served-file.ts +14 -0
- package/source/server.ts +58 -0
- package/source/sql.ts +36 -0
- package/source/storage.ts +66 -0
- package/source/subscribable.ts +94 -0
- package/source/window.ts +82 -0
package/source/main.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export {
|
|
2
|
+
type Message,
|
|
3
|
+
type Cleanup,
|
|
4
|
+
type Capture,
|
|
5
|
+
type Captures,
|
|
6
|
+
type EventMessage,
|
|
7
|
+
type EventName,
|
|
8
|
+
type EventObserver,
|
|
9
|
+
type EventOptions,
|
|
10
|
+
type EventSubscriber,
|
|
11
|
+
type Subscribable
|
|
12
|
+
} from "./subscribable.js"
|
|
13
|
+
|
|
14
|
+
export { type Publishable } from "./publishable.js"
|
|
15
|
+
export { type Askable, type TimedAskable } from "./askable.js"
|
|
16
|
+
export { type Outcome } from "./outcome.js"
|
|
17
|
+
export { type ServedFile } from "./served-file.js"
|
|
18
|
+
export {
|
|
19
|
+
type DirectoryStat,
|
|
20
|
+
type EntryStat,
|
|
21
|
+
type FileStat,
|
|
22
|
+
type OtherStat,
|
|
23
|
+
type ProgramArea,
|
|
24
|
+
type ProgramStore
|
|
25
|
+
} from "./storage.js"
|
|
26
|
+
export { type LogKind, type LogRecord, type LogSource, type ProgramSql } from "./sql.js"
|
|
27
|
+
|
|
28
|
+
export {
|
|
29
|
+
Endpoint,
|
|
30
|
+
type AskCapture,
|
|
31
|
+
type AskMessage,
|
|
32
|
+
type AskObserver,
|
|
33
|
+
type EndpointTraffic,
|
|
34
|
+
type TrafficCapture,
|
|
35
|
+
type TrafficEvents,
|
|
36
|
+
type TrafficMessage
|
|
37
|
+
} from "./endpoint.js"
|
|
38
|
+
export { type Channel, type ChannelCapture, type ChannelEvents, type ChannelMessage } from "./channel.js"
|
|
39
|
+
export {
|
|
40
|
+
Server,
|
|
41
|
+
type AnswerCapture,
|
|
42
|
+
type AnswerMessage,
|
|
43
|
+
type AnswerObserver,
|
|
44
|
+
type ServerTraffic
|
|
45
|
+
} from "./server.js"
|
|
46
|
+
export { Client, type ClientTraffic } from "./client.js"
|
|
47
|
+
export { Process, type Exit, type ProcessEvents } from "./process.js"
|
|
48
|
+
export {
|
|
49
|
+
Program,
|
|
50
|
+
type ClientDeclaration,
|
|
51
|
+
type EndpointDeclaration,
|
|
52
|
+
type ProgramEvents,
|
|
53
|
+
type ProgramProcessExit,
|
|
54
|
+
type ProgramServerStop
|
|
55
|
+
} from "./program.js"
|
|
56
|
+
export { Window, type WindowEvents, type WindowState } from "./window.js"
|
|
57
|
+
export { layers, type Launch, type LaunchClient, type Layer, type Position, type Size, type Value } from "./launch.js"
|
|
58
|
+
export {
|
|
59
|
+
defineConfig,
|
|
60
|
+
type ClientConfig,
|
|
61
|
+
type ClientDevelopment,
|
|
62
|
+
type Config,
|
|
63
|
+
type ServerConfig,
|
|
64
|
+
type ServerDevelopment
|
|
65
|
+
} from "./config.js"
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { Client } from "./client.js"
|
|
2
|
+
import type { Program } from "./program.js"
|
|
3
|
+
import type { Server } from "./server.js"
|
|
4
|
+
import type { Subscribable } from "./subscribable.js"
|
|
5
|
+
|
|
6
|
+
/** How an operating-system-backed endpoint or Process finished. */
|
|
7
|
+
export type Exit = Readonly<{
|
|
8
|
+
/** Whether the endpoint exited normally or was terminated by a signal. */
|
|
9
|
+
status: "exited" | "signaled"
|
|
10
|
+
|
|
11
|
+
/** Numeric exit code, or `null` when no code was reported. */
|
|
12
|
+
code: number | null
|
|
13
|
+
|
|
14
|
+
/** Signal name, or `null` when no signal ended it. */
|
|
15
|
+
signal: string | null
|
|
16
|
+
}>
|
|
17
|
+
|
|
18
|
+
/** Lifecycle events emitted by one Process. */
|
|
19
|
+
export type ProcessEvents = {
|
|
20
|
+
/** The Server entered a new live incarnation. */
|
|
21
|
+
serverStart: undefined
|
|
22
|
+
|
|
23
|
+
/** The Server incarnation ended. */
|
|
24
|
+
serverStop: Omit<Exit, "status">
|
|
25
|
+
|
|
26
|
+
/** The authoritative Client state was created. */
|
|
27
|
+
clientStart: undefined
|
|
28
|
+
|
|
29
|
+
/** The authoritative Client state ended. */
|
|
30
|
+
clientStop: undefined
|
|
31
|
+
|
|
32
|
+
/** The complete Process ended. */
|
|
33
|
+
exit: Exit
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** One live execution of a Program. */
|
|
37
|
+
export class Process<Events extends object = {}> {
|
|
38
|
+
public constructor() {}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface Process<Events extends object = {}> extends Subscribable<ProcessEvents & Events, never> {
|
|
42
|
+
/** Immutable runtime identity. */
|
|
43
|
+
readonly identity: string
|
|
44
|
+
|
|
45
|
+
/** Optional meaningful name unique among this Program's live Processes. */
|
|
46
|
+
readonly name: string | null
|
|
47
|
+
|
|
48
|
+
/** Instant at which this Process was created. */
|
|
49
|
+
readonly startedAt: Date
|
|
50
|
+
|
|
51
|
+
/** Permanent handle to this Process's Server. */
|
|
52
|
+
readonly server: Server
|
|
53
|
+
|
|
54
|
+
/** Permanent handle to this Process's Client. */
|
|
55
|
+
readonly client: Client
|
|
56
|
+
|
|
57
|
+
/** Returns the Program that owns this Process. */
|
|
58
|
+
program(): Program
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Returns the Process whose `createProcess()` call created this Process.
|
|
62
|
+
*
|
|
63
|
+
* Returns `null` when this Process has no accessible parent handle. Rejects
|
|
64
|
+
* when this Process or its retained parent no longer exists. Client
|
|
65
|
+
* environments never expose a parent belonging to another Program.
|
|
66
|
+
*/
|
|
67
|
+
parent(): Promise<Process | null>
|
|
68
|
+
|
|
69
|
+
/** Returns one immutable launch option. */
|
|
70
|
+
option(name: string): Promise<string | undefined>
|
|
71
|
+
|
|
72
|
+
/** Ends the complete Process and all live Endpoints. */
|
|
73
|
+
exit(): Promise<void>
|
|
74
|
+
|
|
75
|
+
/** Returns whether this Process has ended. */
|
|
76
|
+
exited(): Promise<boolean>
|
|
77
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type { Launch, Layer, Position, Size } from "./launch.js"
|
|
2
|
+
import type { Exit, Process } from "./process.js"
|
|
3
|
+
import type { ProgramSql } from "./sql.js"
|
|
4
|
+
import type { ProgramArea, ProgramStore } from "./storage.js"
|
|
5
|
+
import type { Subscribable } from "./subscribable.js"
|
|
6
|
+
|
|
7
|
+
/** Resolved declaration shared by Server and Client endpoint kinds. */
|
|
8
|
+
export type EndpointDeclaration = Readonly<{
|
|
9
|
+
/** Whether a default Process starts this declared Endpoint. */
|
|
10
|
+
start: boolean
|
|
11
|
+
}>
|
|
12
|
+
|
|
13
|
+
/** Resolved Client declaration and its default Window state. */
|
|
14
|
+
export type ClientDeclaration = EndpointDeclaration & Readonly<{
|
|
15
|
+
/** Default Window title, or `null` when the system supplies it. */
|
|
16
|
+
title: string | null
|
|
17
|
+
|
|
18
|
+
/** Default Window size, or `null` when the system supplies it. */
|
|
19
|
+
size: Size | null
|
|
20
|
+
|
|
21
|
+
/** Default Window position, or `null` when the system supplies it. */
|
|
22
|
+
position: Position | null
|
|
23
|
+
|
|
24
|
+
/** Default Window layer, or `null` for the system default. */
|
|
25
|
+
layer: Layer | null
|
|
26
|
+
|
|
27
|
+
/** Default minimized state, or `null` for the system default. */
|
|
28
|
+
minimize: boolean | null
|
|
29
|
+
}>
|
|
30
|
+
|
|
31
|
+
export type ProgramProcessExit = Exit & Readonly<{
|
|
32
|
+
/** Process that ended. */
|
|
33
|
+
process: Process
|
|
34
|
+
}>
|
|
35
|
+
|
|
36
|
+
export type ProgramServerStop = Omit<Exit, "status"> & Readonly<{
|
|
37
|
+
/** Process whose Server incarnation ended. */
|
|
38
|
+
process: Process
|
|
39
|
+
}>
|
|
40
|
+
|
|
41
|
+
/** Lifecycle events scoped to one Program. */
|
|
42
|
+
export type ProgramEvents = {
|
|
43
|
+
/** One Process's Server entered a new live incarnation. */
|
|
44
|
+
serverStart: Process
|
|
45
|
+
|
|
46
|
+
/** One Process's Server incarnation ended. */
|
|
47
|
+
serverStop: ProgramServerStop
|
|
48
|
+
|
|
49
|
+
/** One Process's Client state was created. */
|
|
50
|
+
clientStart: Process
|
|
51
|
+
|
|
52
|
+
/** One Process's Client state ended. */
|
|
53
|
+
clientStop: Process
|
|
54
|
+
|
|
55
|
+
/** A Process entered this Program's runtime set. */
|
|
56
|
+
processCreate: Process
|
|
57
|
+
|
|
58
|
+
/** A Process left this Program's runtime set. */
|
|
59
|
+
processExit: ProgramProcessExit
|
|
60
|
+
|
|
61
|
+
/** This Program left the runtime registry. */
|
|
62
|
+
forget: undefined
|
|
63
|
+
|
|
64
|
+
/** This Program left the installed state. */
|
|
65
|
+
uninstall: Readonly<{ everythingRemoved: boolean }>
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** The stable domain root from which Processes are created. */
|
|
69
|
+
export class Program<Events extends object = {}> {
|
|
70
|
+
public constructor() {}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface Program<Events extends object = {}> extends Subscribable<ProgramEvents & Events, never> {
|
|
74
|
+
/** Stable public identity. */
|
|
75
|
+
readonly identity: string
|
|
76
|
+
|
|
77
|
+
/** Human-readable name. */
|
|
78
|
+
readonly name: string
|
|
79
|
+
|
|
80
|
+
/** Declared version, or `null`. */
|
|
81
|
+
readonly version: string | null
|
|
82
|
+
|
|
83
|
+
/** Declared description, or `null`. */
|
|
84
|
+
readonly description: string | null
|
|
85
|
+
|
|
86
|
+
/** Server declaration, or `null` when this Program cannot start one. */
|
|
87
|
+
readonly server: EndpointDeclaration | null
|
|
88
|
+
|
|
89
|
+
/** Client declaration, or `null` when this Program cannot start one. */
|
|
90
|
+
readonly client: ClientDeclaration | null
|
|
91
|
+
|
|
92
|
+
/** Persistent filesystem data shared by every Process of this Program. */
|
|
93
|
+
readonly data: ProgramArea
|
|
94
|
+
|
|
95
|
+
/** Disposable filesystem data shared by every Process of this Program. */
|
|
96
|
+
readonly cache: ProgramArea
|
|
97
|
+
|
|
98
|
+
/** Persistent key-value storage shared by every Process of this Program. */
|
|
99
|
+
readonly store: ProgramStore
|
|
100
|
+
|
|
101
|
+
/** Read-only SQL access to captured Client and Server output. */
|
|
102
|
+
readonly logs: ProgramSql
|
|
103
|
+
|
|
104
|
+
/** Writable SQLite database owned by this Program. */
|
|
105
|
+
readonly database: ProgramSql
|
|
106
|
+
|
|
107
|
+
/** Returns every live Process of this Program available to this SDK. */
|
|
108
|
+
processes(): Promise<Process[]>
|
|
109
|
+
|
|
110
|
+
/** Finds a live Process by identity or Program-local name. */
|
|
111
|
+
getProcess(identityOrName: string): Promise<Process | null>
|
|
112
|
+
|
|
113
|
+
/** Creates one Process of this Program. */
|
|
114
|
+
createProcess(launch?: Launch): Promise<Process>
|
|
115
|
+
|
|
116
|
+
/** Returns the official Markdown API entry point, or `null`. */
|
|
117
|
+
apiDocs(): Promise<string | null>
|
|
118
|
+
|
|
119
|
+
/** Returns whether this Program currently has an installed form. */
|
|
120
|
+
installed(): Promise<boolean>
|
|
121
|
+
|
|
122
|
+
/** Removes this Program's installed form. */
|
|
123
|
+
uninstall(everything?: boolean): Promise<void>
|
|
124
|
+
|
|
125
|
+
/** Ends all Processes and removes this Program from the runtime registry. */
|
|
126
|
+
forget(): Promise<void>
|
|
127
|
+
|
|
128
|
+
/** Ends every live Process and returns their identities. */
|
|
129
|
+
exitAll(): Promise<string[]>
|
|
130
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { EventMessage, EventName } from "./subscribable.js"
|
|
2
|
+
|
|
3
|
+
// Preserves declared string literals in editor completion while still
|
|
4
|
+
// accepting application-defined event names.
|
|
5
|
+
type OpenEvent = string & {}
|
|
6
|
+
|
|
7
|
+
type AvailableEvent<Events extends object, Fallback> = EventName<Events> | ([Fallback] extends [never] ? never : OpenEvent)
|
|
8
|
+
|
|
9
|
+
type CompatibleEvent<Events extends object, Fallback, Payload> = {
|
|
10
|
+
[Event in EventName<Events>]: Payload extends Events[Event] ? Event : never
|
|
11
|
+
}[EventName<Events>] | ([Fallback] extends [never] ? never : Payload extends Fallback ? OpenEvent : never)
|
|
12
|
+
|
|
13
|
+
interface Publish<Events extends object, Fallback> {
|
|
14
|
+
<Payload, Event extends CompatibleEvent<Events, Fallback, Payload> = CompatibleEvent<Events, Fallback, Payload>>(
|
|
15
|
+
event: Event,
|
|
16
|
+
payload: Payload
|
|
17
|
+
): void
|
|
18
|
+
<Event extends AvailableEvent<Events, Fallback>>(
|
|
19
|
+
event: Event,
|
|
20
|
+
payload: EventMessage<Events, Fallback, Event>
|
|
21
|
+
): void
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The independent capability to publish one payload to a named event.
|
|
26
|
+
*
|
|
27
|
+
* Publishing is synchronous and fire-and-forget. An unavailable destination
|
|
28
|
+
* silently drops the publication; no delivery result is produced.
|
|
29
|
+
*/
|
|
30
|
+
export interface Publishable<Events extends object = {}, Fallback = unknown> {
|
|
31
|
+
/** Publishes one payload to one named event on this target. */
|
|
32
|
+
publish: Publish<Events, Fallback>
|
|
33
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Description of a value stored as a publicly reachable file. */
|
|
2
|
+
export type ServedFile = Readonly<{
|
|
3
|
+
/** Generated filename beneath the public served-files route. */
|
|
4
|
+
file: string
|
|
5
|
+
|
|
6
|
+
/** Detected media type, or `null` when no type is known. */
|
|
7
|
+
type: string | null
|
|
8
|
+
|
|
9
|
+
/** Stored size in bytes. */
|
|
10
|
+
size: number
|
|
11
|
+
|
|
12
|
+
/** Storage time as Unix milliseconds. */
|
|
13
|
+
time: number
|
|
14
|
+
}>
|
package/source/server.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Askable } from "./askable.js"
|
|
2
|
+
import { Endpoint, type EndpointTraffic } from "./endpoint.js"
|
|
3
|
+
import type { Outcome } from "./outcome.js"
|
|
4
|
+
import type { Cleanup } from "./subscribable.js"
|
|
5
|
+
|
|
6
|
+
/** One answer sent by this Server to the Endpoint that asked. */
|
|
7
|
+
export type AnswerMessage<Result = unknown, To = Endpoint> = Readonly<{
|
|
8
|
+
/** Destination Endpoint, or `null` when its identity is outside this boundary. */
|
|
9
|
+
to: To
|
|
10
|
+
|
|
11
|
+
/** Transport-neutral success or failure returned by the answerer. */
|
|
12
|
+
outcome: Outcome<Result>
|
|
13
|
+
}>
|
|
14
|
+
|
|
15
|
+
/** One observed answer sent by this Server. */
|
|
16
|
+
export type AnswerCapture<Result = unknown, To = Endpoint> = Readonly<{
|
|
17
|
+
/** Event originally addressed by the question. */
|
|
18
|
+
event: string
|
|
19
|
+
|
|
20
|
+
/** Correlation identity shared with the original question. */
|
|
21
|
+
questionId: string
|
|
22
|
+
|
|
23
|
+
/** Answer destination and outcome. */
|
|
24
|
+
message: AnswerMessage<Result, To>
|
|
25
|
+
}>
|
|
26
|
+
|
|
27
|
+
/** A callback that observes answers sent by this Server. */
|
|
28
|
+
export type AnswerObserver<Result = unknown, To = Endpoint> = (capture: AnswerCapture<Result, To>) => unknown
|
|
29
|
+
|
|
30
|
+
/** Broad communication originating from one Server, including its answers. */
|
|
31
|
+
export interface ServerTraffic<
|
|
32
|
+
Events extends object = {},
|
|
33
|
+
To = Endpoint,
|
|
34
|
+
AskTo = Server
|
|
35
|
+
> extends EndpointTraffic<Events, To, AskTo> {
|
|
36
|
+
/** Observes answers originating from this Server. */
|
|
37
|
+
observeAnswers<Result = unknown>(observer: AnswerObserver<Result, To>): Cleanup
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** The server Endpoint of a Process. */
|
|
41
|
+
export class Server<Events extends object = {}> extends Endpoint<Events> {
|
|
42
|
+
public constructor() {
|
|
43
|
+
super()
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface Server<Events extends object = {}> extends Askable {
|
|
48
|
+
/** Broad communication originating from this Server. */
|
|
49
|
+
readonly traffic: ServerTraffic<Events>
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Waits until a Server incarnation is ready.
|
|
53
|
+
*
|
|
54
|
+
* Temporary absence remains waitable when the Program declares a Server.
|
|
55
|
+
* The SDK uses its ten-second deadline unless one is supplied.
|
|
56
|
+
*/
|
|
57
|
+
waitReady(timeout?: number): Promise<void>
|
|
58
|
+
}
|
package/source/sql.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** SQL access to a Program-owned database or its read-only logs. */
|
|
2
|
+
export interface ProgramSql {
|
|
3
|
+
/** Executes one statement; template interpolations become bound values. */
|
|
4
|
+
query<Row = Record<string, unknown>>(
|
|
5
|
+
statement: TemplateStringsArray,
|
|
6
|
+
...values: unknown[]
|
|
7
|
+
): Promise<Row[]>
|
|
8
|
+
|
|
9
|
+
/** Executes one statement with optional bound values. */
|
|
10
|
+
query<Row = Record<string, unknown>>(
|
|
11
|
+
statement: string,
|
|
12
|
+
values?: unknown[]
|
|
13
|
+
): Promise<Row[]>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** One captured line from a Program endpoint. */
|
|
17
|
+
export type LogRecord = Readonly<{
|
|
18
|
+
createdAt: number
|
|
19
|
+
process: string
|
|
20
|
+
source: LogSource
|
|
21
|
+
kind: LogKind
|
|
22
|
+
content: string
|
|
23
|
+
}>
|
|
24
|
+
|
|
25
|
+
export type LogSource = "client" | "server"
|
|
26
|
+
|
|
27
|
+
export type LogKind =
|
|
28
|
+
| "debug"
|
|
29
|
+
| "log"
|
|
30
|
+
| "info"
|
|
31
|
+
| "warn"
|
|
32
|
+
| "error"
|
|
33
|
+
| "stdout"
|
|
34
|
+
| "stderr"
|
|
35
|
+
| "exit"
|
|
36
|
+
| (string & {})
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/** Metadata returned for an entry in Program-owned filesystem storage. */
|
|
2
|
+
export type EntryStat = FileStat | DirectoryStat | OtherStat
|
|
3
|
+
|
|
4
|
+
export type FileStat = Readonly<{
|
|
5
|
+
kind: "file"
|
|
6
|
+
size: number
|
|
7
|
+
modifiedAt: number
|
|
8
|
+
}>
|
|
9
|
+
|
|
10
|
+
export type DirectoryStat = Readonly<{
|
|
11
|
+
kind: "directory"
|
|
12
|
+
modifiedAt: number
|
|
13
|
+
}>
|
|
14
|
+
|
|
15
|
+
export type OtherStat = Readonly<{
|
|
16
|
+
kind: "other"
|
|
17
|
+
modifiedAt: number
|
|
18
|
+
}>
|
|
19
|
+
|
|
20
|
+
/** Filesystem-like storage owned by one Program. */
|
|
21
|
+
export interface ProgramArea {
|
|
22
|
+
/** Reads one file as bytes. */
|
|
23
|
+
bytes(...path: string[]): Promise<Uint8Array>
|
|
24
|
+
|
|
25
|
+
/** Reads one UTF-8 text file. */
|
|
26
|
+
text(...path: string[]): Promise<string>
|
|
27
|
+
|
|
28
|
+
/** Reads and parses one JSON file. */
|
|
29
|
+
json<Value = unknown>(...path: string[]): Promise<Value>
|
|
30
|
+
|
|
31
|
+
/** Opens one file as a byte stream. */
|
|
32
|
+
stream(...path: string[]): Promise<ReadableStream<Uint8Array>>
|
|
33
|
+
|
|
34
|
+
/** Atomically writes one supported value, including a byte stream. */
|
|
35
|
+
write(...arguments_: [...path: string[], value: unknown]): Promise<void>
|
|
36
|
+
|
|
37
|
+
/** Returns entry metadata, or `null` when the entry does not exist. */
|
|
38
|
+
stat(...path: string[]): Promise<EntryStat | null>
|
|
39
|
+
|
|
40
|
+
/** Lists the sorted names immediately inside one directory. */
|
|
41
|
+
list(...path: string[]): Promise<string[]>
|
|
42
|
+
|
|
43
|
+
/** Recursively removes an entry. A missing entry is accepted. */
|
|
44
|
+
delete(...path: string[]): Promise<void>
|
|
45
|
+
|
|
46
|
+
/** Removes every entry while preserving the area itself. */
|
|
47
|
+
clear(): Promise<void>
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Persistent key-value storage owned by one Program. */
|
|
51
|
+
export interface ProgramStore {
|
|
52
|
+
/** Returns a value, or `undefined` when its key is absent or expired. */
|
|
53
|
+
get<Value = unknown>(key: string): Promise<Value | undefined>
|
|
54
|
+
|
|
55
|
+
/** Stores a value and optionally expires it after `ttl` milliseconds. */
|
|
56
|
+
set<Value>(key: string, value: Value, ttl?: number): Promise<boolean>
|
|
57
|
+
|
|
58
|
+
/** Deletes one key or several keys and reports whether anything changed. */
|
|
59
|
+
delete(key: string | string[]): Promise<boolean>
|
|
60
|
+
|
|
61
|
+
/** Returns whether a non-expired value exists for one key. */
|
|
62
|
+
has(key: string): Promise<boolean>
|
|
63
|
+
|
|
64
|
+
/** Deletes every value in this Program's store. */
|
|
65
|
+
clear(): Promise<void>
|
|
66
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/** The unconstrained message received by a general Subscribable. */
|
|
2
|
+
export type Message = unknown
|
|
3
|
+
|
|
4
|
+
/** The message observed for one event on a Subscribable. */
|
|
5
|
+
export type Capture<Event extends string = string, Received = Message> = Readonly<{
|
|
6
|
+
/** Name under which the message was published. */
|
|
7
|
+
event: Event
|
|
8
|
+
|
|
9
|
+
/** Message delivered by the observed target. */
|
|
10
|
+
message: Received
|
|
11
|
+
}>
|
|
12
|
+
|
|
13
|
+
/** The string event names declared by an event map. */
|
|
14
|
+
export type EventName<Events extends object> = Extract<keyof Events, string>
|
|
15
|
+
|
|
16
|
+
/** The message declared for one event name. */
|
|
17
|
+
export type EventMessage<Events extends object, Fallback, Event extends string> = Event extends EventName<Events> ? Events[Event] : Fallback
|
|
18
|
+
|
|
19
|
+
/** The correlated union observed across every event declared by a target. */
|
|
20
|
+
export type Captures<Events extends object, Fallback = never> = {
|
|
21
|
+
[Event in EventName<Events>]: Capture<Event, Events[Event]>
|
|
22
|
+
}[EventName<Events>] | ([Fallback] extends [never] ? never : Capture<string, Fallback>)
|
|
23
|
+
|
|
24
|
+
/** A callback for one subscribed message. Its return value is not communication. */
|
|
25
|
+
export type EventSubscriber<Message> = (message: Message) => unknown
|
|
26
|
+
|
|
27
|
+
/** A callback for an observed event and its message. */
|
|
28
|
+
export type EventObserver<Events extends object, Fallback = never> = (capture: Captures<Events, Fallback>) => unknown
|
|
29
|
+
|
|
30
|
+
/** Removes exactly one persistent registration. Safe to call more than once. */
|
|
31
|
+
export type Cleanup = () => void
|
|
32
|
+
|
|
33
|
+
/** Options controlling one asynchronous event iterator. */
|
|
34
|
+
export type EventOptions = Readonly<{
|
|
35
|
+
/** Maximum queued messages. Defaults to `64`; `Infinity` removes the bound. */
|
|
36
|
+
capacity?: number
|
|
37
|
+
|
|
38
|
+
/** Aborts iteration and removes its temporary boundary registration. */
|
|
39
|
+
signal?: AbortSignal
|
|
40
|
+
}>
|
|
41
|
+
|
|
42
|
+
// Preserves declared string literals in editor completion while still
|
|
43
|
+
// accepting application-defined event names.
|
|
44
|
+
type OpenEvent = string & {}
|
|
45
|
+
|
|
46
|
+
type AvailableEvent<Events extends object, Fallback> = EventName<Events> | ([Fallback] extends [never] ? never : OpenEvent)
|
|
47
|
+
|
|
48
|
+
type CompatibleEvent<Events extends object, Fallback, Narrowed> = {
|
|
49
|
+
[Event in EventName<Events>]: Narrowed extends Events[Event] ? Event : never
|
|
50
|
+
}[EventName<Events>] | ([Fallback] extends [never] ? never : Narrowed extends Fallback ? OpenEvent : never)
|
|
51
|
+
|
|
52
|
+
interface Subscribe<Events extends object, Fallback> {
|
|
53
|
+
<Narrowed>(event: CompatibleEvent<Events, Fallback, Narrowed>, subscriber: EventSubscriber<Narrowed>): Cleanup
|
|
54
|
+
<Event extends AvailableEvent<Events, Fallback>>(event: Event, subscriber: EventSubscriber<EventMessage<Events, Fallback, Event>>): Cleanup
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
interface WaitFor<Events extends object, Fallback> {
|
|
58
|
+
<Narrowed>(event: CompatibleEvent<Events, Fallback, Narrowed>, timeout?: number): Promise<Narrowed>
|
|
59
|
+
<Event extends AvailableEvent<Events, Fallback>>(event: Event, timeout?: number): Promise<EventMessage<Events, Fallback, Event>>
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
interface EventStream<Events extends object, Fallback> {
|
|
63
|
+
<Narrowed>(event: CompatibleEvent<Events, Fallback, Narrowed>, options?: EventOptions): AsyncIterableIterator<Narrowed>
|
|
64
|
+
<Event extends AvailableEvent<Events, Fallback>>(event: Event, options?: EventOptions): AsyncIterableIterator<EventMessage<Events, Fallback, Event>>
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
interface Observe<Events extends object, Fallback> {
|
|
68
|
+
(observer: EventObserver<Events, Fallback>): Cleanup
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The common receiving capability supplied by environment SDKs.
|
|
73
|
+
*
|
|
74
|
+
* Persistent registrations return their sole cleanup function. A registration
|
|
75
|
+
* may remain active across temporary endpoint absence and is removed only by
|
|
76
|
+
* that cleanup or by destruction of its owning boundary.
|
|
77
|
+
*
|
|
78
|
+
* `waitFor()` uses the SDK's ten-second deadline unless one is supplied.
|
|
79
|
+
* `events()` is long-lived instead: it ends when iteration is closed, its
|
|
80
|
+
* signal aborts, or the boundary proves that future delivery is impossible.
|
|
81
|
+
*/
|
|
82
|
+
export interface Subscribable<Events extends object = {}, Fallback = unknown> {
|
|
83
|
+
/** Registers one persistent named-event subscription. */
|
|
84
|
+
subscribe: Subscribe<Events, Fallback>
|
|
85
|
+
|
|
86
|
+
/** Waits for the next matching message. */
|
|
87
|
+
waitFor: WaitFor<Events, Fallback>
|
|
88
|
+
|
|
89
|
+
/** Iterates matching messages until closed, aborted, or impossible. */
|
|
90
|
+
events: EventStream<Events, Fallback>
|
|
91
|
+
|
|
92
|
+
/** Registers one persistent observer across every event on this target. */
|
|
93
|
+
observe: Observe<Events, Fallback>
|
|
94
|
+
}
|
package/source/window.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { Client } from "./client.js"
|
|
2
|
+
import type { Layer, Position, Size } from "./launch.js"
|
|
3
|
+
import type { Subscribable } from "./subscribable.js"
|
|
4
|
+
|
|
5
|
+
/** Events emitted when authoritative Window state changes. */
|
|
6
|
+
export type WindowEvents = {
|
|
7
|
+
move: Position
|
|
8
|
+
resize: Size
|
|
9
|
+
minimize: boolean
|
|
10
|
+
changeTitle: string
|
|
11
|
+
front: boolean
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Current authoritative Window state. */
|
|
15
|
+
export type WindowState = Readonly<{
|
|
16
|
+
/** Current title. */
|
|
17
|
+
title: string
|
|
18
|
+
|
|
19
|
+
/** Current top-left position. */
|
|
20
|
+
position: Position
|
|
21
|
+
|
|
22
|
+
/** Current width and height. */
|
|
23
|
+
size: Size
|
|
24
|
+
|
|
25
|
+
/** Whether the Window is minimized. */
|
|
26
|
+
minimized: boolean
|
|
27
|
+
|
|
28
|
+
/** Whether the Window is frontmost in its layer. */
|
|
29
|
+
front: boolean
|
|
30
|
+
|
|
31
|
+
/** Structurally isolated desktop layer containing the Window. */
|
|
32
|
+
layer: Layer
|
|
33
|
+
|
|
34
|
+
/** Current page beneath the declared Client location. */
|
|
35
|
+
location: string
|
|
36
|
+
}>
|
|
37
|
+
|
|
38
|
+
/** The Window owned by one live Client. */
|
|
39
|
+
export class Window<Events extends object = {}> {
|
|
40
|
+
public constructor() {}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface Window<Events extends object = {}> extends Subscribable<WindowEvents & Events, never> {
|
|
44
|
+
/** Returns the Client that owns this Window. */
|
|
45
|
+
client(): Client
|
|
46
|
+
|
|
47
|
+
/** Returns the current title. */
|
|
48
|
+
title(): Promise<string>
|
|
49
|
+
|
|
50
|
+
/** Returns the current top-left position. */
|
|
51
|
+
position(): Promise<Position>
|
|
52
|
+
|
|
53
|
+
/** Returns the current width and height. */
|
|
54
|
+
size(): Promise<Size>
|
|
55
|
+
|
|
56
|
+
/** Returns whether the Window is minimized. */
|
|
57
|
+
minimized(): Promise<boolean>
|
|
58
|
+
|
|
59
|
+
/** Returns whether the Window is frontmost in its layer. */
|
|
60
|
+
front(): Promise<boolean>
|
|
61
|
+
|
|
62
|
+
/** Returns the structurally isolated desktop layer containing the Window. */
|
|
63
|
+
layer(): Promise<Layer>
|
|
64
|
+
|
|
65
|
+
/** Returns the current page rooted beneath the declared Client location. */
|
|
66
|
+
location(): Promise<string>
|
|
67
|
+
|
|
68
|
+
/** Moves the authoritative Window. */
|
|
69
|
+
move(position: Position): Promise<void>
|
|
70
|
+
|
|
71
|
+
/** Resizes the authoritative Window. */
|
|
72
|
+
resize(size: Size): Promise<void>
|
|
73
|
+
|
|
74
|
+
/** Changes whether the Window is minimized. */
|
|
75
|
+
minimize(minimized?: boolean): Promise<void>
|
|
76
|
+
|
|
77
|
+
/** Changes the Window title. */
|
|
78
|
+
changeTitle(title: string): Promise<void>
|
|
79
|
+
|
|
80
|
+
/** Brings the Window to the front of its own layer. */
|
|
81
|
+
raise(): Promise<void>
|
|
82
|
+
}
|