babavoss 0.0.1 → 0.0.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/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
package/src/web/hooks.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// The hooks a view reads the state with, each honest about what it wants:
|
|
2
|
+
// a list is ids, a value is one component of one entity, and a predicate or
|
|
3
|
+
// an order is declared on the select so the table knows what wakes it. Each
|
|
4
|
+
// hook subscribes to the page's store of the baba and re-renders only when
|
|
5
|
+
// its own answer moves; each registers its interest, so the socket carries
|
|
6
|
+
// no more than the page reads. A select is declared once, at module level:
|
|
7
|
+
// the table keeps one live set per select object, and one made in a render
|
|
8
|
+
// is a new one every time.
|
|
9
|
+
import { createContext, useContext, useEffect, useLayoutEffect, useMemo, useSyncExternalStore } from "react";
|
|
10
|
+
import { ScopeContext } from "./core.tsx";
|
|
11
|
+
import { storeFor, type Probe, type StateStore } from "./store.ts";
|
|
12
|
+
import { HandContext, AppStoreContext, UNSET, type Hand, type HookStore } from "./app.tsx";
|
|
13
|
+
import type { Raw } from "../ecs/runtime.ts";
|
|
14
|
+
|
|
15
|
+
/** What a page's live store gives: the state to read, the calls, the standing. The socket store of the page's baba is one; a simulation in the page, which the Maker provides, is another. */
|
|
16
|
+
export interface LiveStore extends HookStore {
|
|
17
|
+
ready: boolean;
|
|
18
|
+
connected: boolean;
|
|
19
|
+
refused: string | null;
|
|
20
|
+
fire(name: string, args?: unknown): Promise<unknown>;
|
|
21
|
+
fireIn(name: string, args?: unknown): Promise<{ value: unknown; round: number | undefined }>;
|
|
22
|
+
read(name: string, args?: unknown): Promise<unknown>;
|
|
23
|
+
raw(op: Raw): Promise<unknown>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** A live store put over a subtree: every useBaba and useBabaState inside fires into it and reads it. */
|
|
27
|
+
export const LiveStoreContext = createContext<LiveStore | null>(null);
|
|
28
|
+
import type { Component, Entity, Resource, Select, Term, Value } from "../ecs/state.ts";
|
|
29
|
+
|
|
30
|
+
/** The state the hooks read: a fixed one, when the component is shown over one (a frame); else the live store put over it (the Maker's simulation); else the store of this page's baba, held while the component is mounted. */
|
|
31
|
+
export function useStore(): HookStore {
|
|
32
|
+
const fixed = useContext(AppStoreContext);
|
|
33
|
+
const over = useContext(LiveStoreContext);
|
|
34
|
+
const scope = useContext(ScopeContext);
|
|
35
|
+
if (!fixed && !over && scope === null) throw new Error("useStore: not inside a baba's page, nor over an app's state");
|
|
36
|
+
const st: HookStore = fixed ?? over ?? storeFor(scope!);
|
|
37
|
+
useEffect(() => st.retain(), [st]);
|
|
38
|
+
return st;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** The page's own live store: what fires actions, reads queries and knows the socket. An app's state does not replace it; a LiveStoreContext does. */
|
|
42
|
+
export function useLiveStore(): LiveStore {
|
|
43
|
+
const over = useContext(LiveStoreContext);
|
|
44
|
+
const scope = useContext(ScopeContext);
|
|
45
|
+
if (!over && scope === null) throw new Error("useLiveStore: not inside a baba's page");
|
|
46
|
+
const st: LiveStore = over ?? (storeFor(scope!) as StateStore as LiveStore);
|
|
47
|
+
useEffect(() => st.retain(), [st]);
|
|
48
|
+
return st;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The hand a component may act with: the one given over it (none, for a frame that only shows), else the live store's,
|
|
53
|
+
* the page's baba or the Maker's simulation; undefined outside both. Acting through it, an app never names whose state it is.
|
|
54
|
+
*/
|
|
55
|
+
export function useHand(): Hand | undefined {
|
|
56
|
+
const given = useContext(HandContext);
|
|
57
|
+
const over = useContext(LiveStoreContext);
|
|
58
|
+
const scope = useContext(ScopeContext);
|
|
59
|
+
return useMemo(() => {
|
|
60
|
+
if (given !== UNSET) return given;
|
|
61
|
+
const st = over ?? (scope !== null ? (storeFor(scope) as StateStore as LiveStore) : null);
|
|
62
|
+
return st ? { fire: (name: string, args?: unknown) => { void st.fire(name, args).catch(() => {}); } } : undefined;
|
|
63
|
+
}, [given, over, scope]);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** A store's value, read the same on the server and in the page: a frame rendered once, or a live store followed. */
|
|
67
|
+
function read<T>(st: HookStore, get: () => T): T { return useSyncExternalStore(st.subscribe, get, get); }
|
|
68
|
+
|
|
69
|
+
function useInterest(st: HookStore, want: () => () => void, deps: unknown[]): void {
|
|
70
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
71
|
+
useEffect(() => want(), [st, ...deps]);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** The entities a declared select answers, in its order: the same array until an entity enters or leaves, or, for a `.where` or a `.by`, until a value it reads is written on a member. A select with change terms answers what the last round changed. */
|
|
75
|
+
export function useQuery<Cs extends readonly Term[]>(sel: Select<Cs>): readonly Entity[] {
|
|
76
|
+
const st = useStore();
|
|
77
|
+
useInterest(st, () => st.wantSelect(sel as never), [sel]);
|
|
78
|
+
return read(st, () => st.replica.ids(sel));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** One column of a select: every member's value of `c` as one map, the same until a member comes, goes or is written. For a component that draws a whole layer at once; a row reads `useComponent`. */
|
|
82
|
+
export function useColumn<Cs extends readonly Term[], K extends Component>(sel: Select<Cs>, c: K): ReadonlyMap<Entity, Value<K>> {
|
|
83
|
+
const st = useStore();
|
|
84
|
+
useInterest(st, () => { const a = st.wantSelect(sel as never), b = st.wantValues(c); return () => { a(); b(); }; }, [sel, c]);
|
|
85
|
+
return read(st, () => st.replica.column(sel as never, c));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** How many entities a select answers. */
|
|
89
|
+
export function useCount<Cs extends readonly Term[]>(sel: Select<Cs>): number { return useQuery(sel).length; }
|
|
90
|
+
|
|
91
|
+
/** The value of `c` on `e`, or undefined without one: the replica's own object, the same until it is written. */
|
|
92
|
+
export function useComponent<K extends Component>(e: Entity, c: K): Value<K> | undefined {
|
|
93
|
+
const st = useStore();
|
|
94
|
+
useInterest(st, () => st.wantPart(e, c), [e, c]);
|
|
95
|
+
return read(st, () => st.replica.get(e, c));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Whether `e` carries `c`. */
|
|
99
|
+
export function useHas(e: Entity, c: Component): boolean {
|
|
100
|
+
const st = useStore();
|
|
101
|
+
useInterest(st, () => st.wantPresence(c), [c]);
|
|
102
|
+
return read(st, () => st.replica.has(e, c));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Whether `e` exists, as far as the window holds: an entity none of the page's interests touch is not here. */
|
|
106
|
+
export function useAlive(e: Entity): boolean {
|
|
107
|
+
const st = useStore();
|
|
108
|
+
return read(st, () => st.replica.alive(e));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** A resource's value: the same object until it is written. */
|
|
112
|
+
export function useResource<K extends Resource>(r: K): Value<K> {
|
|
113
|
+
const st = useStore();
|
|
114
|
+
useInterest(st, () => st.wantResource(r), [r]);
|
|
115
|
+
return read(st, () => st.replica.get(r));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Whether the state has reached `round`: what a `fireIn` answered, so a row shows pending until its effect is in view. */
|
|
119
|
+
export function useSettled(round: number | undefined): boolean {
|
|
120
|
+
const st = useStore();
|
|
121
|
+
return read(st, () => round === undefined || st.replica.round >= round);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** The round the window holds. */
|
|
125
|
+
export function useRound(): number {
|
|
126
|
+
const st = useStore();
|
|
127
|
+
return read(st, () => st.replica.round);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** What following costs this window, round by round. Reading it also times the page's render after each frame. */
|
|
131
|
+
export function useProbe(): Probe {
|
|
132
|
+
const st = useStore();
|
|
133
|
+
useLayoutEffect(() => st.committed());
|
|
134
|
+
return read(st, () => st.probe);
|
|
135
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// babavoss/web: what a view file imports, and what voss's pages are built with.
|
|
2
|
+
export { route, matchRoute, type RouteParams, type RouteMatch } from "../desktop/routes.ts";
|
|
3
|
+
export { compose, view, useScope, useManifest, ScopeProvider, api, apiHeaders, configure, ApiError, type AppsDef, type RouteTable, type InterfaceDef, type ViewDef } from "./core.tsx";
|
|
4
|
+
export { objectsOf, instancesOf, ridersOf, looseOf, ObjectMap, ObjectCards, ObjectCard, type ObjectType } from "./objects.tsx";
|
|
5
|
+
export { Maker, Simulation, asProgram, appsFor, type MakerProps, type AppChoice } from "./maker.tsx";
|
|
6
|
+
export { AppState, AppStoreContext, fixedStore, type Hand, type HookStore } from "./app.tsx";
|
|
7
|
+
export type { StepRecord, CheckRecord } from "../test/records.ts";
|
|
8
|
+
export { useBabaState, useBaba, type BabaStateView, type BabaView, type FollowSample, type Probe } from "./state.tsx";
|
|
9
|
+
export { useQuery, useColumn, useCount, useComponent, useHas, useAlive, useResource, useSettled, useRound, useProbe, useHand, LiveStoreContext, type LiveStore } from "./hooks.ts";
|
|
10
|
+
export { select, not, added, changed, removed } from "../ecs/state.ts";
|
|
11
|
+
export { Replica } from "../ecs/replica.ts";
|
|
12
|
+
export type { Manifest } from "../ecs/baba.ts";
|
|
13
|
+
export { formatFailure, placeOf, type ViewFailure, type Stage as FailureStage } from "../build/failure.ts";
|
|
14
|
+
export { Button, Input, Textarea, Select, Kbd, Panel, Rows, Row, Table, Dialog, CommandList, type ButtonVariant } from "./ui.tsx";
|
|
15
|
+
export { plan, collect, tableOf, describeType, FieldError, type Plan, type Field, type Values } from "./form.ts";
|
|
16
|
+
export { filterItems, type Item } from "./list.ts";
|
|
17
|
+
export { Desktop, DesktopFrame, SpecDesktop, LocalDesktop, Eyes, AppIcon, desktopAddress, parseDesktopAddress, parseDesktopHash, routeOf, type DesktopProps, type AppProps, type SurfaceProps } from "../desktop/view.tsx";
|
package/src/web/list.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// A command list's filter and its keyboard selection. Pure.
|
|
2
|
+
|
|
3
|
+
export interface Item { id: string; group: string; label: string; hint?: string }
|
|
4
|
+
|
|
5
|
+
/** The items every word of the query appears in, by group, label or hint, in their order. */
|
|
6
|
+
export function filterItems<T extends Item>(list: T[], query: string): T[] {
|
|
7
|
+
const words = query.toLowerCase().split(/\s+/).filter(Boolean);
|
|
8
|
+
if (words.length === 0) return list;
|
|
9
|
+
return list.filter((e) => {
|
|
10
|
+
const hay = `${e.group} ${e.label} ${e.hint ?? ""}`.toLowerCase();
|
|
11
|
+
return words.every((w) => hay.includes(w));
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** The selection after an arrow key, wrapping at both ends. */
|
|
16
|
+
export function move(index: number, by: number, length: number): number {
|
|
17
|
+
if (length === 0) return 0;
|
|
18
|
+
return (((index + by) % length) + length) % length;
|
|
19
|
+
}
|