@dcasegr/skein 0.0.0-stage → 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/README.md +525 -2
- package/bin/skein-host.js +22 -0
- package/bin/skein.js +8 -0
- package/dist/client/admin-cli.d.ts +10 -0
- package/dist/client/admin-cli.js +370 -0
- package/dist/client/admin.d.ts +139 -0
- package/dist/client/admin.js +256 -0
- package/dist/client/bundle.d.ts +9 -0
- package/dist/client/bundle.js +34 -0
- package/dist/client/cli.d.ts +44 -0
- package/dist/client/cli.js +306 -0
- package/dist/client/client.d.ts +161 -0
- package/dist/client/client.js +237 -0
- package/dist/client/config.d.ts +18 -0
- package/dist/client/config.js +31 -0
- package/dist/client/conversation.d.ts +62 -0
- package/dist/client/conversation.js +113 -0
- package/dist/client/raw.d.ts +94 -0
- package/dist/client/raw.js +154 -0
- package/dist/client/target.d.ts +34 -0
- package/dist/client/target.js +158 -0
- package/dist/dev/cli.d.ts +8 -0
- package/dist/dev/cli.js +248 -0
- package/dist/dev/scan.d.ts +15 -0
- package/dist/dev/scan.js +173 -0
- package/dist/envelope-cbor.d.ts +110 -0
- package/dist/envelope-cbor.js +160 -0
- package/dist/envelope.d.ts +38 -0
- package/dist/envelope.js +101 -0
- package/dist/host/arc.d.ts +131 -0
- package/dist/host/arc.js +425 -0
- package/dist/host/billing.d.ts +102 -0
- package/dist/host/billing.js +167 -0
- package/dist/host/boot.d.ts +246 -0
- package/dist/host/boot.js +643 -0
- package/dist/host/cli.d.ts +57 -0
- package/dist/host/cli.js +1253 -0
- package/dist/host/clock.d.ts +3 -0
- package/dist/host/clock.js +8 -0
- package/dist/host/control.d.ts +45 -0
- package/dist/host/control.js +170 -0
- package/dist/host/cron.d.ts +99 -0
- package/dist/host/cron.js +196 -0
- package/dist/host/deliver.d.ts +53 -0
- package/dist/host/deliver.js +251 -0
- package/dist/host/deploy.d.ts +29 -0
- package/dist/host/deploy.js +55 -0
- package/dist/host/door-answer.d.ts +24 -0
- package/dist/host/door-answer.js +21 -0
- package/dist/host/events.d.ts +89 -0
- package/dist/host/events.js +222 -0
- package/dist/host/fake-arcade.d.ts +40 -0
- package/dist/host/fake-arcade.js +149 -0
- package/dist/host/fake-discovery.d.ts +4 -0
- package/dist/host/fake-discovery.js +58 -0
- package/dist/host/feeds.d.ts +127 -0
- package/dist/host/feeds.js +422 -0
- package/dist/host/frontdoor.d.ts +92 -0
- package/dist/host/frontdoor.js +172 -0
- package/dist/host/genesis.d.ts +259 -0
- package/dist/host/genesis.js +353 -0
- package/dist/host/handles.d.ts +40 -0
- package/dist/host/handles.js +88 -0
- package/dist/host/hostenv.d.ts +30 -0
- package/dist/host/hostenv.js +83 -0
- package/dist/host/image-chain.d.ts +127 -0
- package/dist/host/image-chain.js +440 -0
- package/dist/host/install.d.ts +22 -0
- package/dist/host/install.js +139 -0
- package/dist/host/instances.d.ts +227 -0
- package/dist/host/instances.js +430 -0
- package/dist/host/kernel.d.ts +246 -0
- package/dist/host/kernel.js +603 -0
- package/dist/host/liveness.d.ts +65 -0
- package/dist/host/liveness.js +155 -0
- package/dist/host/manifest.d.ts +160 -0
- package/dist/host/manifest.js +597 -0
- package/dist/host/p2p.d.ts +337 -0
- package/dist/host/p2p.js +1002 -0
- package/dist/host/packet.d.ts +121 -0
- package/dist/host/packet.js +562 -0
- package/dist/host/plan.d.ts +154 -0
- package/dist/host/plan.js +418 -0
- package/dist/host/providers.d.ts +238 -0
- package/dist/host/providers.js +565 -0
- package/dist/host/roster.d.ts +72 -0
- package/dist/host/roster.js +172 -0
- package/dist/host/router.d.ts +782 -0
- package/dist/host/router.js +2411 -0
- package/dist/host/signer.d.ts +49 -0
- package/dist/host/signer.js +167 -0
- package/dist/host/store-sqlite.d.ts +39 -0
- package/dist/host/store-sqlite.js +170 -0
- package/dist/host/stores.d.ts +43 -0
- package/dist/host/stores.js +342 -0
- package/dist/host/sync.d.ts +121 -0
- package/dist/host/sync.js +467 -0
- package/dist/host/testbeef.d.ts +21 -0
- package/dist/host/testbeef.js +37 -0
- package/dist/host/testhost.d.ts +149 -0
- package/dist/host/testhost.js +211 -0
- package/dist/host/vcdiff.d.ts +9 -0
- package/dist/host/vcdiff.js +210 -0
- package/dist/host/wasm-kernel.d.ts +87 -0
- package/dist/host/wasm-kernel.js +296 -0
- package/dist/host/wasm-worker.d.ts +1 -0
- package/dist/host/wasm-worker.js +186 -0
- package/dist/peers/cron.d.ts +33 -0
- package/dist/peers/cron.js +75 -0
- package/dist/peers/infer-main.d.ts +2 -0
- package/dist/peers/infer-main.js +74 -0
- package/dist/peers/infer.d.ts +163 -0
- package/dist/peers/infer.js +367 -0
- package/dist/runtime/beef.d.ts +28 -0
- package/dist/runtime/beef.js +107 -0
- package/dist/runtime/bitcoin.d.ts +36 -0
- package/dist/runtime/bitcoin.js +141 -0
- package/dist/runtime/cid.d.ts +14 -0
- package/dist/runtime/cid.js +51 -0
- package/dist/runtime/dispatch.d.ts +92 -0
- package/dist/runtime/dispatch.js +142 -0
- package/dist/runtime/envelope.d.ts +60 -0
- package/dist/runtime/envelope.js +101 -0
- package/dist/runtime/heads.d.ts +25 -0
- package/dist/runtime/heads.js +37 -0
- package/dist/runtime/identity.d.ts +28 -0
- package/dist/runtime/identity.js +67 -0
- package/dist/runtime/index-store.d.ts +152 -0
- package/dist/runtime/index-store.js +715 -0
- package/dist/runtime/log.d.ts +62 -0
- package/dist/runtime/log.js +104 -0
- package/dist/runtime/programs.d.ts +30 -0
- package/dist/runtime/programs.js +61 -0
- package/dist/runtime/records.d.ts +135 -0
- package/dist/runtime/records.js +149 -0
- package/dist/runtime/sqlite.d.ts +33 -0
- package/dist/runtime/sqlite.js +604 -0
- package/dist/runtime/store.d.ts +141 -0
- package/dist/runtime/store.js +24 -0
- package/dist/runtime/syscalls.d.ts +9 -0
- package/dist/runtime/syscalls.js +41 -0
- package/dist/runtime/tree.d.ts +60 -0
- package/dist/runtime/tree.js +196 -0
- package/dist/runtime/types.d.ts +100 -0
- package/dist/runtime/types.js +7 -0
- package/dist/testapps.d.ts +101 -0
- package/dist/testapps.js +275 -0
- package/dist/testkit.d.ts +25 -0
- package/dist/testkit.js +48 -0
- package/dist/wallet.d.ts +35 -0
- package/dist/wallet.js +87 -0
- package/images/README.md +68 -0
- package/images/default/README.md +38 -0
- package/images/default/bin/frontdoor.cid +1 -0
- package/images/default/bin/frontdoor.json +5 -0
- package/images/default/bin/messagebox.cid +1 -0
- package/images/default/bin/messagebox.json +8 -0
- package/images/default/bin/wallet.cid +1 -0
- package/images/default/bin/wallet.json +14 -0
- package/images/default/etc/config.json +1 -0
- package/images/default/etc/dispatch.json +82 -0
- package/images/host/etc/apps.json +8 -0
- package/kernel-zig/README.md +1247 -0
- package/kernel-zig/web/client.js +65 -0
- package/kernel-zig/web/kernel.d.ts +59 -0
- package/kernel-zig/web/kernel.js +329 -0
- package/kernel-zig/web/store.js +67 -0
- package/kernel-zig/web/worker.js +79 -0
- package/kernel-zig/zig-out/web/skein-kernel.wasm +0 -0
- package/package.json +77 -4
- package/wasm/README.md +35 -0
- package/wasm/frontdoor.wasm +0 -0
- package/wasm/messagebox.wasm +0 -0
- package/wasm/resolve.wasm +0 -0
- package/wasm/wallet.wasm +0 -0
- package/wasm/wire-probe.wasm +0 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// The liveness tool (#138): a runtime handler keyed by event name, like the
|
|
2
|
+
// deadline, fetch and beacon handlers (#126). An app's installed program
|
|
3
|
+
// declares, once per topic,
|
|
4
|
+
//
|
|
5
|
+
// liveness {event: "liveness", topic, window: <ms, a second to a day>}
|
|
6
|
+
// unliveness {event: "unliveness", topic}
|
|
7
|
+
//
|
|
8
|
+
// and the kernel records it on the step's update (kernel-zig/src/
|
|
9
|
+
// subscriptions.zig livenessProblem / livenessFold). Here, for each liveness
|
|
10
|
+
// topic the apps keep (folded from the log, livenessOf, then followed live):
|
|
11
|
+
//
|
|
12
|
+
// - the instance's own libp2p node subscribes the topic WITHOUT admitting
|
|
13
|
+
// its messages: no front-door call, no entry, nothing logged (P2PHost:
|
|
14
|
+
// a topic only liveness takes is judged here alone);
|
|
15
|
+
// - each message is a beacon beat (p2p.ts beaconFrame: {body, at, sender,
|
|
16
|
+
// signature}); its instance signature is checked (beaconBeat) and a beat
|
|
17
|
+
// that does not verify is dropped (and rejected to GossipSub);
|
|
18
|
+
// - the beats newer than the window are kept, the latest per sender
|
|
19
|
+
// (identity key), with the peer that published it (`from`); the node's
|
|
20
|
+
// OWN beats on the topic are written into the same set (gossip does not
|
|
21
|
+
// echo them: P2PHost.beacons);
|
|
22
|
+
// - in memory only: empty after a restart until the next beats; dropped at
|
|
23
|
+
// the app's unliveness or uninstall.
|
|
24
|
+
//
|
|
25
|
+
// The set is served to the app's page by the host itself, no program in
|
|
26
|
+
// between (Router: GET /<app>/.live/<topic> on the instance's origin).
|
|
27
|
+
// A runtime without this tool records the events and nothing happens.
|
|
28
|
+
import { beaconBeat, emittedEvents, isTopic } from "./p2p.js";
|
|
29
|
+
/** A window's bounds (ms): a second, a day (subscriptions.zig LIVENESS_MIN_MS / _MAX_MS). */
|
|
30
|
+
export const LIVENESS_MIN_MS = 1000;
|
|
31
|
+
export const LIVENESS_MAX_MS = 86_400_000;
|
|
32
|
+
/** A `liveness` / `unliveness` event record, read (subscriptions.zig livenessEventOf); or why it is not one this host follows. */
|
|
33
|
+
export function livenessEvent(rec) {
|
|
34
|
+
const event = rec.event;
|
|
35
|
+
if (rec.kind !== "event" || (event !== "liveness" && event !== "unliveness"))
|
|
36
|
+
return { refused: "not a liveness or unliveness event" };
|
|
37
|
+
if (typeof rec.app !== "string" || !rec.app)
|
|
38
|
+
return { refused: "it names no app (its program record is not installed): ignored" };
|
|
39
|
+
if (!isTopic(rec.topic))
|
|
40
|
+
return { refused: `${JSON.stringify(rec.topic)} is not a topic` };
|
|
41
|
+
if (event === "unliveness")
|
|
42
|
+
return { event, app: rec.app, topic: rec.topic };
|
|
43
|
+
const window = typeof rec.window === "number" ? rec.window : typeof rec.window === "bigint" ? Number(rec.window) : NaN;
|
|
44
|
+
if (!Number.isInteger(window) || window < LIVENESS_MIN_MS || window > LIVENESS_MAX_MS)
|
|
45
|
+
return { refused: "a liveness window is from a second to a day (`window`, ms)" };
|
|
46
|
+
return { event, live: { app: rec.app, topic: rec.topic, window } };
|
|
47
|
+
}
|
|
48
|
+
/** Fold liveness events in order: a liveness replaces the app's own on the topic, an unliveness removes it. */
|
|
49
|
+
export function foldLiveness(events, into = []) {
|
|
50
|
+
for (const e of events) {
|
|
51
|
+
const [app, topic] = e.event === "liveness" ? [e.live.app, e.live.topic] : [e.app, e.topic];
|
|
52
|
+
const i = into.findIndex((l) => l.app === app && l.topic === topic);
|
|
53
|
+
if (e.event === "liveness") {
|
|
54
|
+
if (i >= 0)
|
|
55
|
+
into[i] = e.live;
|
|
56
|
+
else
|
|
57
|
+
into.push(e.live);
|
|
58
|
+
}
|
|
59
|
+
else if (i >= 0)
|
|
60
|
+
into.splice(i, 1);
|
|
61
|
+
}
|
|
62
|
+
return into;
|
|
63
|
+
}
|
|
64
|
+
/** The liveness standing, folded from the store's log as the subscriptions and beacons are (p2p.ts subscriptionsOf). Read only. */
|
|
65
|
+
export async function livenessOf(store) {
|
|
66
|
+
return foldLiveness(await emittedEvents(store, (rec) => { const e = livenessEvent(rec); return "refused" in e ? undefined : e; }));
|
|
67
|
+
}
|
|
68
|
+
/** The tool's state: per instance, the apps' liveness and the beats kept per topic (in memory). */
|
|
69
|
+
export class Liveness {
|
|
70
|
+
lives = new Map();
|
|
71
|
+
/** handle → topic → sender → the latest beat. */
|
|
72
|
+
beats = new Map();
|
|
73
|
+
now;
|
|
74
|
+
/** Told each beat newly kept (shruggr/skein#150: the overlay's sync reads a peer's tip anchor from it). */
|
|
75
|
+
kept;
|
|
76
|
+
constructor(now = Date.now) { this.now = now; }
|
|
77
|
+
/** `handle`'s apps keep this liveness now: the beats of topics none keeps any more are dropped. */
|
|
78
|
+
set(handle, lives) {
|
|
79
|
+
if (!lives.length) {
|
|
80
|
+
this.drop(handle);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
this.lives.set(handle, lives.map((l) => ({ ...l })));
|
|
84
|
+
const kept = this.beats.get(handle);
|
|
85
|
+
if (kept)
|
|
86
|
+
for (const t of kept.keys())
|
|
87
|
+
if (!lives.some((l) => l.topic === t))
|
|
88
|
+
kept.delete(t);
|
|
89
|
+
}
|
|
90
|
+
/** The topics `handle`'s apps keep liveness for (each once). */
|
|
91
|
+
topics(handle) { return [...new Set((this.lives.get(handle) ?? []).map((l) => l.topic))]; }
|
|
92
|
+
/** Whether an app of `handle` keeps liveness for `topic`. */
|
|
93
|
+
takes(handle, topic) { return (this.lives.get(handle) ?? []).some((l) => l.topic === topic); }
|
|
94
|
+
/** The longest window on `topic` among `handle`'s apps (ms), or undefined. */
|
|
95
|
+
windowOf(handle, topic) {
|
|
96
|
+
const ws = (this.lives.get(handle) ?? []).filter((l) => l.topic === topic).map((l) => l.window);
|
|
97
|
+
return ws.length ? Math.max(...ws) : undefined;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* A message on `topic` at `handle`'s node, published by peer `from`: kept when it is a beat whose
|
|
101
|
+
* instance signature verifies (beaconBeat) and is newer than the longest window on the topic — the
|
|
102
|
+
* sender's latest replaces an older one. Nothing logged.
|
|
103
|
+
*/
|
|
104
|
+
observe(handle, topic, frame, from) {
|
|
105
|
+
const window = this.windowOf(handle, topic);
|
|
106
|
+
if (window === undefined)
|
|
107
|
+
return "ignore";
|
|
108
|
+
const b = beaconBeat(topic, frame);
|
|
109
|
+
if ("problem" in b)
|
|
110
|
+
return "reject";
|
|
111
|
+
const now = this.now();
|
|
112
|
+
// A beat older than the window is not live; one dated more than a window ahead of this clock is not believed.
|
|
113
|
+
if (now - b.at >= window || b.at - now > window)
|
|
114
|
+
return "ignore";
|
|
115
|
+
let byTopic = this.beats.get(handle);
|
|
116
|
+
if (!byTopic)
|
|
117
|
+
this.beats.set(handle, byTopic = new Map());
|
|
118
|
+
let bySender = byTopic.get(topic);
|
|
119
|
+
if (!bySender)
|
|
120
|
+
byTopic.set(topic, bySender = new Map());
|
|
121
|
+
const sender = Buffer.from(b.sender).toString("hex");
|
|
122
|
+
const was = bySender.get(sender);
|
|
123
|
+
if (!was || b.at > was.at) {
|
|
124
|
+
const beat = { sender, at: b.at, body: b.body, from };
|
|
125
|
+
bySender.set(sender, beat);
|
|
126
|
+
this.kept?.(handle, topic, beat);
|
|
127
|
+
}
|
|
128
|
+
// The stale ones go as the set is touched.
|
|
129
|
+
for (const [k, x] of bySender)
|
|
130
|
+
if (now - x.at >= window)
|
|
131
|
+
bySender.delete(k);
|
|
132
|
+
return "accept";
|
|
133
|
+
}
|
|
134
|
+
/** The beats live for `app`'s liveness on `topic` (newer than its window), newest first; undefined: the app keeps no liveness for the topic. */
|
|
135
|
+
read(handle, app, topic) {
|
|
136
|
+
const l = (this.lives.get(handle) ?? []).find((x) => x.app === app && x.topic === topic);
|
|
137
|
+
if (!l)
|
|
138
|
+
return undefined;
|
|
139
|
+
const now = this.now();
|
|
140
|
+
return [...(this.beats.get(handle)?.get(topic)?.values() ?? [])].filter((b) => now - b.at < l.window).sort((x, y) => y.at - x.at);
|
|
141
|
+
}
|
|
142
|
+
/** Every beat live on `topic` at `handle` (newer than the longest window on it), whichever app keeps it. */
|
|
143
|
+
live(handle, topic) {
|
|
144
|
+
const window = this.windowOf(handle, topic);
|
|
145
|
+
if (window === undefined)
|
|
146
|
+
return [];
|
|
147
|
+
const now = this.now();
|
|
148
|
+
return [...(this.beats.get(handle)?.get(topic)?.values() ?? [])].filter((b) => now - b.at < window);
|
|
149
|
+
}
|
|
150
|
+
/** Forget `handle`: its liveness and its beats. */
|
|
151
|
+
drop(handle) {
|
|
152
|
+
this.lives.delete(handle);
|
|
153
|
+
this.beats.delete(handle);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
export type RouteTransport = "mailbox" | "event" | "http" | "libp2p";
|
|
2
|
+
/** A route as the manifest writes it (#143). */
|
|
3
|
+
export interface RouteIn {
|
|
4
|
+
transport?: RouteTransport;
|
|
5
|
+
address: string;
|
|
6
|
+
prefix?: true;
|
|
7
|
+
filters?: string[];
|
|
8
|
+
handler?: string;
|
|
9
|
+
[setting: string]: unknown;
|
|
10
|
+
}
|
|
11
|
+
export interface FunctionDecl {
|
|
12
|
+
writes: boolean;
|
|
13
|
+
args?: unknown;
|
|
14
|
+
answer?: unknown;
|
|
15
|
+
}
|
|
16
|
+
export interface Provide {
|
|
17
|
+
interface: string;
|
|
18
|
+
functions: Record<string, FunctionDecl>;
|
|
19
|
+
}
|
|
20
|
+
export interface Manifest {
|
|
21
|
+
kind: "app";
|
|
22
|
+
name: string;
|
|
23
|
+
version: string;
|
|
24
|
+
programs: Record<string, string | Record<string, unknown>>;
|
|
25
|
+
routes?: RouteIn[];
|
|
26
|
+
filters?: Record<string, string>;
|
|
27
|
+
roles?: Record<string, string[]>;
|
|
28
|
+
config?: Record<string, unknown>;
|
|
29
|
+
provides?: Provide[];
|
|
30
|
+
requires?: string[];
|
|
31
|
+
start?: {
|
|
32
|
+
body: Record<string, unknown>;
|
|
33
|
+
};
|
|
34
|
+
stop?: {
|
|
35
|
+
body: Record<string, unknown>;
|
|
36
|
+
};
|
|
37
|
+
description?: string;
|
|
38
|
+
}
|
|
39
|
+
/** A shell program's support for one command (#25, #83): files mounted read-only at `mount` for that command only, env defaults. */
|
|
40
|
+
export interface ShellSupport {
|
|
41
|
+
mount: string;
|
|
42
|
+
files: Record<string, string>;
|
|
43
|
+
env: Record<string, string>;
|
|
44
|
+
}
|
|
45
|
+
/** A shell program as the manifest names it (#83): its modules and support files, paths in the tree. */
|
|
46
|
+
export interface ShellSource {
|
|
47
|
+
kind: "shell";
|
|
48
|
+
modules: Record<string, string>;
|
|
49
|
+
support: Record<string, ShellSupport>;
|
|
50
|
+
description?: string;
|
|
51
|
+
}
|
|
52
|
+
/** Where a role's program comes from. */
|
|
53
|
+
export type ProgramSource = {
|
|
54
|
+
kind: "wasm" | "cid";
|
|
55
|
+
path: string;
|
|
56
|
+
name: string;
|
|
57
|
+
} | {
|
|
58
|
+
kind: "instance";
|
|
59
|
+
name: string;
|
|
60
|
+
} | ShellSource;
|
|
61
|
+
/** A route normalised: transport set; the address, filters and handler as written. */
|
|
62
|
+
export type Route = RouteIn & {
|
|
63
|
+
transport: RouteTransport;
|
|
64
|
+
};
|
|
65
|
+
/** A manifest checked: the fields as installed. */
|
|
66
|
+
export interface Checked {
|
|
67
|
+
manifest: Omit<Manifest, "routes"> & {
|
|
68
|
+
routes: Route[];
|
|
69
|
+
provides: Provide[];
|
|
70
|
+
requires: string[];
|
|
71
|
+
};
|
|
72
|
+
sources: Record<string, ProgramSource>;
|
|
73
|
+
/** What `config.overlay` added (APPS.md §6): route keys (routeKey). */
|
|
74
|
+
derived: Derived;
|
|
75
|
+
}
|
|
76
|
+
export declare class ManifestError extends Error {
|
|
77
|
+
readonly problems: string[];
|
|
78
|
+
constructor(problems: string[]);
|
|
79
|
+
}
|
|
80
|
+
export declare const RESERVED_NAMES: string[];
|
|
81
|
+
/** Why `shape` is not a shape (APPS.md §2), or undefined. */
|
|
82
|
+
export declare function shapeProblem(shape: unknown, at: string): string | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* An http route's path as served: relative to /<app>/ (a leading "/" too). Throws
|
|
85
|
+
* on anything that could name a path outside that prefix.
|
|
86
|
+
*/
|
|
87
|
+
export declare function appPath(app: string, p: string): string;
|
|
88
|
+
/**
|
|
89
|
+
* A box as the kernel's table holds it (#128): relative to the app, as an http
|
|
90
|
+
* path is — "" or the app's own name is the app's box `<app>`; "x" is `<app>/x`. Throws on a
|
|
91
|
+
* box that is not one: an empty, "." or ".." segment (a leading, trailing or doubled "/"),
|
|
92
|
+
* whitespace or a control character, or more than 128 bytes resolved (the messagebox
|
|
93
|
+
* server's limit).
|
|
94
|
+
*/
|
|
95
|
+
export declare function appBox(app: string, b: string): string;
|
|
96
|
+
/** A route's address as served: an http path under /<app>/ (appPath); a box under the app's (appBox); a libp2p name as written. */
|
|
97
|
+
export declare function rowAddress(app: string, r: {
|
|
98
|
+
transport: string;
|
|
99
|
+
address: string;
|
|
100
|
+
}): string;
|
|
101
|
+
/** A route's key as the kernel's table knows it (dispatch.ts rowKey): `<transport> <address as served>[ prefix]`. */
|
|
102
|
+
export declare function routeKey(app: string, r: {
|
|
103
|
+
transport: string;
|
|
104
|
+
address: string;
|
|
105
|
+
prefix?: boolean;
|
|
106
|
+
}): string;
|
|
107
|
+
/**
|
|
108
|
+
* A handler (or a declared filter's function) resolved against the app's programs (#143):
|
|
109
|
+
* "<role>.<fn>"; a bare name that is a role — the program, no function named; any other bare name
|
|
110
|
+
* — a function of the app's one program. Undefined: none of these.
|
|
111
|
+
*/
|
|
112
|
+
export declare function handlerOf(h: unknown, roles: string[]): {
|
|
113
|
+
role: string;
|
|
114
|
+
fn?: string;
|
|
115
|
+
} | undefined;
|
|
116
|
+
/** A route's filter as the kernel's table names it (#143): the kernel's; an own filter's name → `<app>.<name>`; another app's as written. */
|
|
117
|
+
export declare const filterRef: (app: string, f: string) => string;
|
|
118
|
+
/** Check and normalise a manifest. `has(path)`: whether the tree has a file at the path. */
|
|
119
|
+
export declare function checkManifest(json: unknown, has: (path: string) => boolean): Checked;
|
|
120
|
+
/**
|
|
121
|
+
* A shell program as the manifest names it (#83), checked: `code: "shell"`;
|
|
122
|
+
* `modules` command → bin/<x>.wasm in the tree, brush and coreutils among
|
|
123
|
+
* them (every other name a command the shell runs; two names may share a
|
|
124
|
+
* module: `node` is qjs); `support` per command of `modules`: an absolute
|
|
125
|
+
* `mount`, `files` (path under the mount → a file in the tree), `env` text →
|
|
126
|
+
* text. The install turns it into the record the kernel's shell runs.
|
|
127
|
+
*/
|
|
128
|
+
export declare function shellSource(p: Record<string, unknown>, has: (path: string) => boolean, at: string): ShellSource | string[];
|
|
129
|
+
/** The role of an overlay app's engine (its `config.overlay` is the engine's). */
|
|
130
|
+
export declare const OVERLAY_ROLE = "overlay";
|
|
131
|
+
/** What the install derived from `config.overlay` (route keys), for the prompt. */
|
|
132
|
+
export interface Derived {
|
|
133
|
+
routes: string[];
|
|
134
|
+
}
|
|
135
|
+
/** An overlay app's wiring. */
|
|
136
|
+
export interface OverlayWiring {
|
|
137
|
+
routes: Route[];
|
|
138
|
+
topics: string[];
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* The wiring `config.overlay` asks for (APPS.md §6, #79, #143), or its problems. For each topic:
|
|
142
|
+
* the libp2p routes `<topic>` → submit (kernel.beef), `<topic>-admit` → peerAdmit, `<topic>-proof`
|
|
143
|
+
* → peerProof; the http route `/submit` (kernel.beef: a submission validates itself — #135, signed
|
|
144
|
+
* or validated) and `/lookup` (BRC-24's POST: answered by the engine's `lookup`, a filter — a read
|
|
145
|
+
* route, nothing logged); and the app's own box twice: an `event` route (what its libp2p routes
|
|
146
|
+
* admit — a gossiped submission, a peer's admit) and a `mailbox` route (its own watch of a
|
|
147
|
+
* submission the chain app has accepted, sent by the host's loopback). All to the role `overlay`,
|
|
148
|
+
* the engine, which the manifest must declare `lookup` a filter of. No `chain` or `status` box (the
|
|
149
|
+
* chain app's): the engine writes `<app>/…` only. No topics is accepted: the box routes, `/submit`
|
|
150
|
+
* and `/lookup` and no per-topic routes — the topics registered at runtime get theirs from the
|
|
151
|
+
* engine (#120). `market` ({window: <ms>}), `validator` ({every: <ms>}) and `terms` (a map, the
|
|
152
|
+
* beat's initial terms: skein-overlay 0.17.0) are the engine's own settings, read from the app record:
|
|
153
|
+
* checked, no routes derived. A field other than these is
|
|
154
|
+
* refused (no prefix declarations, #120). `isRole` tells which roles the manifest has.
|
|
155
|
+
*/
|
|
156
|
+
export declare function overlayWiring(app: string, ov: unknown, isRole: (role: string) => boolean): OverlayWiring | string[];
|
|
157
|
+
/** The interfaces `requires` names that no installed app provides. */
|
|
158
|
+
export declare function missingInterfaces(requires: string[], installed: Array<{
|
|
159
|
+
provides?: Provide[];
|
|
160
|
+
}>): string[];
|