babavoss 0.0.1 → 0.12.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/NOTICE +7 -0
- package/bin/voss.ts +48 -0
- package/gui/babavoss-web.js +234 -0
- package/gui/chunk-5hpp1ypv.js +11710 -0
- package/gui/chunk-9rq662fd.js +8627 -0
- package/gui/chunk-k3cm8j6r.js +433 -0
- package/gui/chunk-pk09y98y.js +50 -0
- package/gui/chunk-smz02qa6.js +186 -0
- package/gui/chunk-wwqypxre.js +49 -0
- package/gui/gui.js +2015 -0
- package/gui/react-compiler-runtime.js +39 -0
- package/gui/react-dom-client.js +21 -0
- package/gui/react-dom.js +44 -0
- package/gui/react-jsx-runtime.js +19 -0
- package/gui/react.js +105 -0
- package/gui/theme.css +3053 -0
- package/index.ts +15 -0
- package/package.json +50 -4
- package/src/baba/check.ts +90 -0
- package/src/baba/config.ts +261 -0
- package/src/baba/find.ts +12 -0
- package/src/baba/init.ts +176 -0
- package/src/baba/node.ts +483 -0
- package/src/baba/project.ts +63 -0
- package/src/baba/registry.ts +35 -0
- package/src/baba/worker.ts +55 -0
- package/src/bench/index.ts +6 -0
- package/src/bench/measure.ts +132 -0
- package/src/bench/scenarios.ts +136 -0
- package/src/build/builder.ts +74 -0
- package/src/build/failure.ts +78 -0
- package/src/build/guard.ts +85 -0
- package/src/build/mdx-register.ts +3 -0
- package/src/build/mdx.ts +38 -0
- package/src/build/project.ts +38 -0
- package/src/build/views.ts +146 -0
- package/src/builder/main.ts +29 -0
- package/src/desktop/bob.ts +76 -0
- package/src/desktop/desktop.css +111 -0
- package/src/desktop/icons.ts +50 -0
- package/src/desktop/index.ts +323 -0
- package/src/desktop/routes.ts +98 -0
- package/src/desktop/view.tsx +673 -0
- package/src/door/core.ts +384 -0
- package/src/ecs/baba.ts +431 -0
- package/src/ecs/codec.ts +334 -0
- package/src/ecs/handles.ts +91 -0
- package/src/ecs/replica.ts +150 -0
- package/src/ecs/runtime.ts +603 -0
- package/src/ecs/scheduler.ts +75 -0
- package/src/ecs/snapshot.ts +102 -0
- package/src/ecs/state.ts +759 -0
- package/src/ecs/system.ts +256 -0
- package/src/ecs/table.ts +420 -0
- package/src/ecs/testbed.ts +97 -0
- package/src/exec/host.ts +177 -0
- package/src/exec/main.ts +98 -0
- package/src/exec/watch.ts +7 -0
- package/src/exec/wire.ts +29 -0
- package/src/generated/build.ts +4 -0
- package/src/gui/css.d.ts +1 -0
- package/src/gui/gui.tsx +245 -0
- package/src/gui/index.ts +51 -0
- package/src/gui/inspector.tsx +47 -0
- package/src/gui/levels.tsx +73 -0
- package/src/gui/promptware.tsx +68 -0
- package/src/gui/runner.tsx +118 -0
- package/src/gui/theme.css +498 -0
- package/src/gui/theme.ts +25 -0
- package/src/gui/wizard.tsx +227 -0
- package/src/guide/add-a-desktop.mdx +100 -0
- package/src/guide/compose-an-interface.mdx +84 -0
- package/src/guide/index.ts +13 -0
- package/src/guide/reach-outside.mdx +112 -0
- package/src/guide/spec-a-system.mdx +93 -0
- package/src/guide/systems-together.mdx +72 -0
- package/src/guide/write-a-system.mdx +183 -0
- package/src/guide/write-promptware.mdx +90 -0
- package/src/http/server.ts +310 -0
- package/src/kernel/build.ts +21 -0
- package/src/kernel/builder.ts +105 -0
- package/src/kernel/children.ts +117 -0
- package/src/kernel/context.ts +90 -0
- package/src/kernel/lock.ts +46 -0
- package/src/kernel/names.ts +14 -0
- package/src/kernel/schema.ts +130 -0
- package/src/kernel/where.ts +12 -0
- package/src/kit/index.ts +232 -0
- package/src/maker/system.ts +213 -0
- package/src/mcp/daemon.ts +61 -0
- package/src/mcp/main.ts +208 -0
- package/src/mcp/rpc.ts +64 -0
- package/src/mcp/tools.ts +125 -0
- package/src/prompt/evals.ts +42 -0
- package/src/prompt/index.ts +242 -0
- package/src/prompt/jsx-dev-runtime.ts +1 -0
- package/src/prompt/jsx-runtime.ts +49 -0
- package/src/prompt/mdx.d.ts +1 -0
- package/src/promptware/compile.ts +183 -0
- package/src/promptware/define.ts +16 -0
- package/src/promptware/disk.ts +72 -0
- package/src/promptware/markdown.d.ts +6 -0
- package/src/promptware/sync.ts +437 -0
- package/src/promptware/system.ts +215 -0
- package/src/runtime/bridge.ts +85 -0
- package/src/runtime/connect.ts +54 -0
- package/src/runtime/env.ts +35 -0
- package/src/runtime/harness.ts +80 -0
- package/src/runtime/main.ts +119 -0
- package/src/runtime/worker.ts +33 -0
- package/src/server/edge.ts +332 -0
- package/src/server/main.ts +45 -0
- package/src/server/messages.ts +97 -0
- package/src/server/protocol.ts +37 -0
- package/src/services/args.ts +45 -0
- package/src/services/exec.ts +69 -0
- package/src/services/fs.ts +139 -0
- package/src/services/http.ts +30 -0
- package/src/services/index.ts +113 -0
- package/src/services/secrets.ts +18 -0
- package/src/shell/address.ts +21 -0
- package/src/shell/args.ts +219 -0
- package/src/shell/client.ts +107 -0
- package/src/shell/codes.ts +26 -0
- package/src/shell/positional.ts +20 -0
- package/src/shell/run.ts +470 -0
- package/src/shell/service.ts +167 -0
- package/src/shell/state.ts +204 -0
- package/src/spec/adapters.ts +72 -0
- package/src/spec/diff.ts +26 -0
- package/src/spec/files.ts +17 -0
- package/src/spec/index.ts +155 -0
- package/src/spec/run.ts +97 -0
- package/src/spec/take.ts +54 -0
- package/src/test/index.ts +8 -0
- package/src/test/prove.ts +56 -0
- package/src/test/records.ts +23 -0
- package/src/test/specs.ts +56 -0
- package/src/test/steps.ts +100 -0
- package/src/test/voss-dir.ts +17 -0
- package/src/transport/messages.ts +110 -0
- package/src/transport/transport.ts +62 -0
- package/src/wall/probe.ts +67 -0
- package/src/wall/profile.ts +103 -0
- package/src/wall/spawn.ts +59 -0
- package/src/web/app.tsx +53 -0
- package/src/web/core.tsx +140 -0
- package/src/web/form.ts +155 -0
- package/src/web/hooks.ts +135 -0
- package/src/web/index.tsx +17 -0
- package/src/web/list.ts +19 -0
- package/src/web/maker.tsx +766 -0
- package/src/web/objects.tsx +213 -0
- package/src/web/socket.ts +84 -0
- package/src/web/state.tsx +69 -0
- package/src/web/store.ts +221 -0
- package/src/web/ui.tsx +135 -0
- package/README.md +0 -5
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// The runtime's clock and timers, behind one interface, so a state can run
|
|
2
|
+
// on the machine's time (the running baba) or on a virtual time a driver
|
|
3
|
+
// advances (a testbed, a live simulation in the page). Every timer the
|
|
4
|
+
// runtime sets goes through here: a round due, a source listing again, a
|
|
5
|
+
// scheduled effect. Nothing in the runtime reads Date or sets a timeout
|
|
6
|
+
// itself.
|
|
7
|
+
|
|
8
|
+
export type Handle = { cancel(): void };
|
|
9
|
+
|
|
10
|
+
export interface Scheduler {
|
|
11
|
+
/** The time, ms since the epoch or since a virtual zero. */
|
|
12
|
+
now(): number;
|
|
13
|
+
/** Runs `fn` once `now()` reaches `at`; at once when it already has. */
|
|
14
|
+
at(when: number, fn: () => void): Handle;
|
|
15
|
+
/** Runs `fn` on the next turn, after everything already queued: a round that takes every message already in flight. */
|
|
16
|
+
soon(fn: () => void): Handle;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** The machine's time: what the running baba uses. Timers are unref'd so a runtime never keeps a process alive on its own. */
|
|
20
|
+
export function realScheduler(): Scheduler {
|
|
21
|
+
const unref = (t: unknown) => { (t as { unref?: () => void }).unref?.(); };
|
|
22
|
+
return {
|
|
23
|
+
now: () => Date.now(),
|
|
24
|
+
at(when, fn) { const t = setTimeout(fn, Math.max(0, when - Date.now())); unref(t); return { cancel: () => clearTimeout(t) }; },
|
|
25
|
+
soon(fn) { const t = setTimeout(fn, 0); unref(t); return { cancel: () => clearTimeout(t) }; },
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A time a driver advances. `advance(to)` runs every timer due up to `to`
|
|
31
|
+
* in time order, each at its own moment, so a round due at 200 and a
|
|
32
|
+
* listing due at 150 happen as they would on the machine, only faster
|
|
33
|
+
* and reproducibly. `soon` runs at the current moment, before any timer
|
|
34
|
+
* due later, at the next advance (or `flush`).
|
|
35
|
+
*/
|
|
36
|
+
export interface VirtualScheduler extends Scheduler {
|
|
37
|
+
/** Runs what is due up to and including `to`, then sets the time to `to`. */
|
|
38
|
+
advance(to: number): void;
|
|
39
|
+
/** Runs what is queued for now, without moving time. */
|
|
40
|
+
flush(): void;
|
|
41
|
+
/** The earliest moment anything is due, or null. */
|
|
42
|
+
next(): number | null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function virtualScheduler(start = 0): VirtualScheduler {
|
|
46
|
+
let now = start;
|
|
47
|
+
let seq = 0;
|
|
48
|
+
type Timer = { at: number; seq: number; fn: () => void; live: boolean };
|
|
49
|
+
const timers: Timer[] = [];
|
|
50
|
+
const add = (at: number, fn: () => void): Handle => { const t: Timer = { at, seq: seq++, fn, live: true }; timers.push(t); return { cancel: () => { t.live = false; } }; };
|
|
51
|
+
const takeDue = (upTo: number): Timer | undefined => {
|
|
52
|
+
let best: Timer | undefined;
|
|
53
|
+
for (const t of timers) if (t.live && t.at <= upTo && (!best || t.at < best.at || (t.at === best.at && t.seq < best.seq))) best = t;
|
|
54
|
+
if (best) timers.splice(timers.indexOf(best), 1);
|
|
55
|
+
return best;
|
|
56
|
+
};
|
|
57
|
+
const sweep = () => { for (let i = timers.length - 1; i >= 0; i--) if (!timers[i]!.live) timers.splice(i, 1); };
|
|
58
|
+
const run = (upTo: number) => {
|
|
59
|
+
for (let guard = 0; guard < 100_000; guard++) {
|
|
60
|
+
const t = takeDue(upTo);
|
|
61
|
+
if (!t) break;
|
|
62
|
+
if (t.at > now) now = t.at;
|
|
63
|
+
t.fn();
|
|
64
|
+
}
|
|
65
|
+
sweep();
|
|
66
|
+
};
|
|
67
|
+
return {
|
|
68
|
+
now: () => now,
|
|
69
|
+
at: (when, fn) => add(Math.max(when, now), fn),
|
|
70
|
+
soon: (fn) => add(now, fn),
|
|
71
|
+
advance(to) { if (to < now) to = now; run(to); now = to; },
|
|
72
|
+
flush() { run(now); },
|
|
73
|
+
next() { let n: number | null = null; for (const t of timers) if (t.live && (n === null || t.at < n)) n = t.at; return n; },
|
|
74
|
+
};
|
|
75
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// The state as JSON, whole or as a delta, and the functions that move a
|
|
2
|
+
// whole by a delta. Pure, browser-safe: the runtime makes them, the node,
|
|
3
|
+
// the replica and the doors apply them.
|
|
4
|
+
import type { Snapshot } from "./state.ts";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* What changed between round `since` and round `round`. Per entity that
|
|
8
|
+
* changed: the components written since, by name, each its value, or null
|
|
9
|
+
* for one taken away; null for an entity that is gone. A new entity's every
|
|
10
|
+
* part is in. Every resource that changed. The jobs, settlements and
|
|
11
|
+
* remembered answers, each only when it changed since. A follower at
|
|
12
|
+
* `since` applies it to its whole.
|
|
13
|
+
*/
|
|
14
|
+
export interface Delta {
|
|
15
|
+
kind: "delta";
|
|
16
|
+
round: number;
|
|
17
|
+
since: number;
|
|
18
|
+
entities: Record<string, Record<string, unknown> | null>;
|
|
19
|
+
resources: Record<string, unknown>;
|
|
20
|
+
jobs?: Snapshot["jobs"];
|
|
21
|
+
next?: number;
|
|
22
|
+
settled?: Snapshot["settled"];
|
|
23
|
+
keys?: Snapshot["keys"];
|
|
24
|
+
/** The makers of the entities in `entities`, those a system made. */
|
|
25
|
+
made?: Record<string, string>;
|
|
26
|
+
/** The parts that arrived since, by entity: a follower that tracks presence alone needs these and not the writes. */
|
|
27
|
+
added?: Record<string, string[]>;
|
|
28
|
+
/** The round's time, as `w.now` had it. */
|
|
29
|
+
now?: number;
|
|
30
|
+
/** The state of `w.random()`, so a kept state draws on as it would have. */
|
|
31
|
+
rng?: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type StateAnswer = Snapshot | Delta;
|
|
35
|
+
|
|
36
|
+
/** In place of a value a follower asked only the presence of: the part is there, its value is not held. */
|
|
37
|
+
export const PRESENT: unknown = Object.freeze({ present: true });
|
|
38
|
+
|
|
39
|
+
export const isDelta = (x: unknown): x is Delta => typeof x === "object" && x !== null && (x as { kind?: unknown }).kind === "delta";
|
|
40
|
+
|
|
41
|
+
/** The whole at `delta.round`, from the whole at `delta.since`, changed in place: a keeper pays for what changed, not for what exists. A delta from another round than the whole's is refused. */
|
|
42
|
+
export function patchSnapshot(whole: Snapshot, delta: Delta): Snapshot {
|
|
43
|
+
if (delta.since !== whole.round) throw new Error(`a delta since round ${delta.since} does not apply to round ${whole.round}`);
|
|
44
|
+
const made = whole.made ?? (whole.made = {});
|
|
45
|
+
for (const [id, patch] of Object.entries(delta.entities)) {
|
|
46
|
+
if (patch === null) { delete whole.entities[id]; delete made[id]; continue; }
|
|
47
|
+
// A patched entity gets a new parts object, so a whole copied shallowly before shares nothing with it after.
|
|
48
|
+
const parts = { ...(whole.entities[id] ?? {}) };
|
|
49
|
+
for (const [name, v] of Object.entries(patch)) { if (v === null) delete parts[name]; else parts[name] = v; }
|
|
50
|
+
whole.entities[id] = parts;
|
|
51
|
+
if (delta.made?.[id] !== undefined) made[id] = delta.made[id]!;
|
|
52
|
+
}
|
|
53
|
+
Object.assign(whole.resources, delta.resources);
|
|
54
|
+
whole.round = delta.round;
|
|
55
|
+
if (delta.jobs !== undefined) whole.jobs = delta.jobs;
|
|
56
|
+
if (delta.next !== undefined) whole.next = delta.next;
|
|
57
|
+
if (delta.settled !== undefined) whole.settled = delta.settled;
|
|
58
|
+
if (delta.keys !== undefined) whole.keys = delta.keys;
|
|
59
|
+
if (delta.now !== undefined) whole.now = delta.now;
|
|
60
|
+
if (delta.rng !== undefined) whole.rng = delta.rng;
|
|
61
|
+
return whole;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** The same move on a copy: the input is not changed. */
|
|
65
|
+
export function applyDelta(whole: Snapshot, delta: Delta): Snapshot {
|
|
66
|
+
return patchSnapshot({ ...whole, entities: { ...whole.entities }, resources: { ...whole.resources }, made: { ...(whole.made ?? {}) } }, delta);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Several consecutive deltas as one, from the first's `since` to the last's `round`: what a follower a few rounds behind applies at once. */
|
|
70
|
+
export function mergeDeltas(deltas: Delta[]): Delta {
|
|
71
|
+
const first = deltas[0]!, last = deltas[deltas.length - 1]!;
|
|
72
|
+
const out: Delta = { kind: "delta", round: last.round, since: first.since, entities: {}, resources: {} };
|
|
73
|
+
const made: Record<string, string> = {};
|
|
74
|
+
let anyMade = false;
|
|
75
|
+
for (const [i, d] of deltas.entries()) {
|
|
76
|
+
if (i > 0 && d.since !== deltas[i - 1]!.round) throw new Error("deltas to merge are not consecutive");
|
|
77
|
+
for (const [id, patch] of Object.entries(d.entities)) {
|
|
78
|
+
if (patch === null) { out.entities[id] = null; delete made[id]; continue; }
|
|
79
|
+
const had = out.entities[id];
|
|
80
|
+
out.entities[id] = had ? { ...had, ...patch } : { ...patch };
|
|
81
|
+
if (d.made?.[id] !== undefined) made[id] = d.made[id]!;
|
|
82
|
+
}
|
|
83
|
+
if (d.made) anyMade = true;
|
|
84
|
+
Object.assign(out.resources, d.resources);
|
|
85
|
+
if (d.jobs !== undefined) out.jobs = d.jobs;
|
|
86
|
+
if (d.next !== undefined) out.next = d.next;
|
|
87
|
+
if (d.settled !== undefined) out.settled = d.settled;
|
|
88
|
+
if (d.keys !== undefined) out.keys = d.keys;
|
|
89
|
+
if (d.now !== undefined) out.now = d.now;
|
|
90
|
+
if (d.rng !== undefined) out.rng = d.rng;
|
|
91
|
+
if (d.added) { out.added ??= {}; for (const [id, names] of Object.entries(d.added)) { const have = out.added[id] ?? []; out.added[id] = [...new Set([...have, ...names])]; } }
|
|
92
|
+
}
|
|
93
|
+
if (anyMade) out.made = made;
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** A whole or a delta applied to the whole a follower holds; a whole replaces it. */
|
|
98
|
+
export function follow(whole: Snapshot | null, answer: StateAnswer): Snapshot {
|
|
99
|
+
if (!isDelta(answer)) return answer;
|
|
100
|
+
if (!whole) throw new Error("a delta arrived before any whole");
|
|
101
|
+
return applyDelta(whole, answer);
|
|
102
|
+
}
|