api_binding_ui 1.1.0 → 2.0.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 +74 -394
- package/SKILL.md +49 -350
- package/dist/framework/contract.d.ts +268 -0
- package/dist/framework/engine.d.ts +88 -0
- package/dist/framework/expr.d.ts +34 -0
- package/dist/framework/loadCatalog.d.ts +6 -0
- package/dist/framework/names.d.ts +7 -0
- package/dist/framework/openapi.d.ts +7 -0
- package/dist/framework/runner.d.ts +33 -0
- package/dist/framework/schema.d.ts +22 -0
- package/dist/framework/store.d.ts +17 -0
- package/dist/framework/validate.d.ts +7 -0
- package/dist/index-e9twc25y.js +754 -0
- package/dist/index-e9twc25y.js.map +16 -0
- package/dist/index.d.ts +11 -29
- package/dist/index.js +345 -11932
- package/dist/index.js.map +14 -0
- package/dist/runtime/BindingProvider.d.ts +42 -0
- package/dist/runtime/BindingScreen.d.ts +23 -0
- package/dist/runtime/hooks.d.ts +22 -0
- package/dist/runtime/screenStore.d.ts +7 -0
- package/dist/studio/ApiPicker.d.ts +15 -0
- package/dist/studio/BindingStudio.d.ts +21 -0
- package/dist/studio/BindingWidget.d.ts +9 -0
- package/dist/studio/Collapse.d.ts +6 -0
- package/dist/studio/ComponentList.d.ts +10 -0
- package/dist/studio/FindAnything.d.ts +7 -0
- package/dist/studio/Inspector.d.ts +12 -0
- package/dist/studio/Navigator.d.ts +17 -0
- package/dist/studio/SettingsPanel.d.ts +15 -0
- package/dist/studio/Tip.d.ts +23 -0
- package/dist/studio/editors/ConsumeEditor.d.ts +4 -0
- package/dist/studio/editors/RequestInputs.d.ts +11 -0
- package/dist/studio/editors/ScopedEditor.d.ts +3 -0
- package/dist/studio/editors/SlotSection.d.ts +3 -0
- package/dist/studio/editors/SourceSelect.d.ts +10 -0
- package/dist/studio/editors/StepCard.d.ts +12 -0
- package/dist/studio/editors/TriggerEditor.d.ts +4 -0
- package/dist/studio/editors/types.d.ts +14 -0
- package/dist/studio/icons.d.ts +65 -0
- package/dist/studio/index.css +2021 -0
- package/dist/studio/index.d.ts +3 -0
- package/dist/studio/index.js +2806 -0
- package/dist/studio/index.js.map +33 -0
- package/dist/studio/useBindings.d.ts +20 -0
- package/dist/studio/useCatalog.d.ts +15 -0
- package/dist/studio/useGlide.d.ts +11 -0
- package/dist/studio/useSettings.d.ts +8 -0
- package/package.json +20 -14
- package/spec/FRAMEWORK.md +271 -0
- package/dist/api-binding-ui.css +0 -248
- package/dist/components/ApiBindingWorkspace.d.ts +0 -10
- package/dist/components/ApiMappings.d.ts +0 -21
- package/dist/components/BindApiButton.d.ts +0 -41
- package/dist/components/RequestPreview.d.ts +0 -7
- package/dist/components/SimulationDialog.d.ts +0 -8
- package/dist/components/ValidationDialog.d.ts +0 -8
- package/dist/components/WorkspaceContext.d.ts +0 -7
- package/dist/components/ui/AppGrid.d.ts +0 -27
- package/dist/components/ui/Badge.d.ts +0 -9
- package/dist/components/ui/Banner.d.ts +0 -8
- package/dist/components/ui/Button.d.ts +0 -31
- package/dist/components/ui/Card.d.ts +0 -14
- package/dist/components/ui/Dialog.d.ts +0 -61
- package/dist/components/ui/Icons.d.ts +0 -21
- package/dist/components/ui/Input.d.ts +0 -31
- package/dist/core/bindingContext.d.ts +0 -67
- package/dist/core/catalog.d.ts +0 -18
- package/dist/core/componentId.d.ts +0 -12
- package/dist/core/model.d.ts +0 -63
- package/dist/core/openapi.d.ts +0 -2
- package/dist/core/transport.d.ts +0 -33
- package/dist/core/validation.d.ts +0 -2
- package/dist/core/valueCoercion.d.ts +0 -17
- package/dist/hooks/useAppliedBinding.d.ts +0 -6
- package/dist/index.css +0 -248
- package/dist/style.css +0 -244
- package/dist/types.d.ts +0 -245
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/framework/expr.ts", "../src/framework/runner.ts", "../src/runtime/BindingScreen.tsx", "../src/runtime/screenStore.ts", "../src/runtime/hooks.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Expression evaluator (FRAMEWORK.md §7). One grammar for every source:\n *\n * <bindId>.<slot>[.path] a produce slot on this screen\n * $item[.path] the current item (scoped slot or forEach)\n * $context.<id>[.path] a value the screen received\n * $steps.<stepId>[.path] an earlier call step's result ({ response })\n * $<provider>[.path] a registered context provider\n * <expr>[*].<path> every item of a list\n * <expr> | name(args) a registered transform\n *\n * Nothing outside this grammar is evaluated; unknown heads resolve to undefined.\n */\n\nexport type Transforms = Record<string, (value: unknown, ...args: unknown[]) => unknown>;\n\nexport interface Scope {\n /** Current value of a produce slot on the screen. */\n slot: (bindId: string, slotId: string) => unknown;\n item?: unknown;\n context?: Record<string, unknown>;\n providers?: Record<string, unknown>;\n steps?: Record<string, unknown>;\n transforms?: Transforms;\n}\n\ninterface Parsed { head: string[]; path: string[]; pipes: Array<{ name: string; args: unknown[] }> }\n\nconst PIPE = /^([A-Za-z_][\\w-]*)\\((.*)\\)$/;\nconst cache = new Map<string, Parsed>();\n\nfunction parseArg(raw: string): unknown {\n const t = raw.trim();\n if (!t) return undefined;\n try { return JSON.parse(t); } catch { return t; }\n}\n\n/** \"a.b[*].c\" → [\"a\", \"b\", \"*\", \"c\"] */\nfunction segments(path: string): string[] {\n return path.replace(/\\[(\\*|\\d+)\\]/g, \".$1\").split(\".\").filter(Boolean);\n}\n\nexport function parse(expr: string): Parsed {\n const hit = cache.get(expr);\n if (hit) return hit;\n const [main, ...rest] = expr.split(\"|\");\n const segs = segments(main.trim());\n if (!segs.length) throw new Error(`Empty expression: \"${expr}\"`);\n // Heads: $item / $context.<id> / $steps.<id> / $<provider> take one or two segments; a component slot takes two.\n const width = segs[0] === \"$item\" || (segs[0].startsWith(\"$\") && ![\"$context\", \"$steps\"].includes(segs[0])) ? 1 : 2;\n const pipes = rest.map(p => {\n const m = PIPE.exec(p.trim());\n if (!m) throw new Error(`Bad transform \"${p.trim()}\" in \"${expr}\"`);\n return { name: m[1], args: m[2] ? m[2].split(\",\").map(parseArg) : [] };\n });\n const parsed = { head: segs.slice(0, width), path: segs.slice(width), pipes };\n cache.set(expr, parsed);\n return parsed;\n}\n\nfunction walk(value: unknown, path: string[]): unknown {\n let v = value;\n for (let i = 0; i < path.length; i++) {\n if (v == null) return undefined;\n if (path[i] === \"*\") {\n if (!Array.isArray(v)) return undefined;\n const rest = path.slice(i + 1);\n return v.map(x => walk(x, rest));\n }\n v = (v as Record<string, unknown>)[path[i]];\n }\n return v;\n}\n\nexport function evaluate(expr: string, scope: Scope): unknown {\n const { head, path, pipes } = parse(expr);\n let root: unknown;\n if (head[0] === \"$item\") root = scope.item;\n else if (head[0] === \"$context\") root = scope.context?.[head[1]];\n else if (head[0] === \"$steps\") root = scope.steps?.[head[1]];\n else if (head[0].startsWith(\"$\")) root = scope.providers?.[head[0].slice(1)];\n else root = scope.slot(head[0], head[1]);\n let value = walk(root, path);\n for (const p of pipes) {\n const fn = scope.transforms?.[p.name];\n if (!fn) throw new Error(`Unknown transform \"${p.name}\" in \"${expr}\"`);\n value = fn(value, ...p.args);\n }\n return value;\n}\n\n",
|
|
6
|
+
"/** Builds requests, reads responses and runs trigger steps. */\nimport type { CatalogOperation, OperationConsumeBinding, Step } from \"./contract\";\nimport { evaluate, type Scope } from \"./expr\";\n\nexport interface HttpRequest {\n method: string;\n /** Path with parameters filled in, e.g. \"/cls/v1/notes/42\". */\n path: string;\n query: Record<string, string>;\n headers: Record<string, string>;\n body?: unknown;\n}\n\n/** Sends a request. Supplied by the host (base URL, auth, errors). */\nexport type Fetcher = (request: HttpRequest, operation: CatalogOperation) => Promise<unknown>;\n\nexport class BindingError extends Error {\n constructor(message: string, readonly detail?: unknown) { super(message); this.name = \"BindingError\"; }\n}\n\nfunction setPointer(target: Record<string, unknown>, keys: string[], value: unknown) {\n let node = target;\n keys.slice(0, -1).forEach(k => { node = (node[k] ??= {}) as Record<string, unknown>; });\n node[keys[keys.length - 1]] = value;\n}\n\nconst decode = (k: string) => k.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n\nexport function buildRequest(op: CatalogOperation, request: Record<string, string>, scope: Scope): HttpRequest {\n const out: HttpRequest = { method: op.method, path: op.path, query: {}, headers: {} };\n let body: Record<string, unknown> | undefined;\n for (const [pointer, expr] of Object.entries(request)) {\n const value = evaluate(expr, scope);\n if (value === undefined) continue;\n const [, where, ...rest] = pointer.split(\"/\");\n const keys = rest.map(decode);\n if (where === \"path\") out.path = out.path.replace(`{${keys[0]}}`, encodeURIComponent(String(value)));\n else if (where === \"query\") out.query[keys[0]] = String(value);\n else if (where === \"header\") out.headers[keys[0]] = String(value);\n else if (where === \"body\") {\n if (!keys.length) out.body = value;\n else setPointer((body ??= {}), keys, value);\n }\n }\n if (body) out.body = { ...(out.body as object | undefined), ...body };\n const missing = op.parameters.filter(p => p.required && !(p.pointer in request && evaluate(request[p.pointer], scope) !== undefined));\n if (missing.length) throw new BindingError(`Missing required input: ${missing.map(p => p.name).join(\", \")}.`);\n return out;\n}\n\n/** Identical requests share a key, and so one fetch. */\nexport const requestKey = (r: HttpRequest) => JSON.stringify([r.method, r.path, r.query, r.body ?? null]);\n\n/** \"$\", \"$.a.b\" or \"$.a.items[*]\" applied to a response. */\nexport function select(response: unknown, selector: string): unknown {\n const path = selector.replace(/^\\$\\.?/, \"\").replace(/\\[\\*\\]$/, \"\").split(\".\").filter(Boolean);\n return path.reduce<unknown>((v, k) => (v == null ? undefined : (v as Record<string, unknown>)[k]), response);\n}\n\n/** Applies a consume binding's `map` to each item; without a map the items pass through untouched. */\nexport function mapItems(data: unknown, binding: OperationConsumeBinding, scope: Scope): unknown {\n if (!binding.map || !Object.keys(binding.map).length) return data;\n const one = (item: unknown) => Object.fromEntries(Object.entries(binding.map!).map(([k, e]) => [k, evaluate(e, { ...scope, item })]));\n return Array.isArray(data) ? data.map(one) : data == null ? data : one(data);\n}\n\nexport async function runConsume(binding: OperationConsumeBinding, op: CatalogOperation, scope: Scope, fetcher: Fetcher): Promise<unknown> {\n const response = await fetcher(buildRequest(op, binding.request, scope), op);\n return mapItems(select(response, binding.select), binding, scope);\n}\n\nexport interface StepOutcome { step: string; ok: boolean; response?: unknown; error?: unknown }\n\n/** Runs call steps in order. `forEach` runs a call once per item; `onError: \"stop\"` ends the run at the first failure. */\nexport async function runSteps(steps: Step[], operations: Map<string, CatalogOperation>, scope: Scope, fetcher: Fetcher): Promise<StepOutcome[]> {\n const outcomes: StepOutcome[] = [];\n const results: Record<string, unknown> = { ...scope.steps };\n for (const step of steps) {\n const op = operations.get(step.operation);\n if (!op) throw new BindingError(`Operation \"${step.operation}\" is not in the catalog.`);\n const items = step.forEach ? evaluate(step.forEach, scope) : [scope.item];\n const list = Array.isArray(items) ? items : [items];\n const responses: unknown[] = [];\n let failed = false;\n for (const item of list) {\n try {\n responses.push(await fetcher(buildRequest(op, step.request, { ...scope, item, steps: results }), op));\n } catch (error) {\n failed = true;\n outcomes.push({ step: step.id, ok: false, error });\n if (step.onError === \"stop\") return outcomes;\n }\n }\n const response = step.forEach ? responses : responses[0];\n results[step.id] = { response };\n if (!failed) outcomes.push({ step: step.id, ok: true, response });\n }\n return outcomes;\n}\n",
|
|
7
|
+
"import * as React from \"react\";\nimport type { ScreenId } from \"../framework/contract\";\nimport { useBindingRuntime } from \"./BindingProvider\";\nimport { createScreenStore, type ScreenStore } from \"./screenStore\";\n\nexport interface ScreenScope {\n id: ScreenId;\n store: ScreenStore;\n /** Values passed in, keyed by the registry entry's `context` ids. */\n context: Record<string, unknown>;\n}\n\nconst ScreenContext = React.createContext<ScreenScope | null>(null);\nconst ShownContext = React.createContext(true);\n\nexport function useScreen(): ScreenScope {\n const s = React.useContext(ScreenContext);\n if (!s) throw new Error(\"Use binding hooks inside <BindingScreen id=…>.\");\n return s;\n}\n\n/** Marks a subtree that stays mounted while hidden (inactive tabs, cached views). */\nexport function BindingActive({ value, children }: { value: boolean; children: React.ReactNode }) {\n const parent = React.useContext(ShownContext);\n return <ShownContext.Provider value={parent && value}>{children}</ShownContext.Provider>;\n}\n\nexport interface BindingScreenProps {\n /** The screen's id in the registry. */\n id: ScreenId;\n context?: Record<string, unknown>;\n children: React.ReactNode;\n}\n\nconst NO_CONTEXT: Record<string, unknown> = {};\n\n/** Binding scope for one screen: its produce values and context. */\nexport function BindingScreen({ id, context = NO_CONTEXT, children }: BindingScreenProps) {\n const [store] = React.useState(createScreenStore);\n const shown = React.useContext(ShownContext);\n const { loadSaved, mountScreen } = useBindingRuntime();\n React.useEffect(() => { loadSaved(id); }, [loadSaved, id]);\n React.useEffect(() => mountScreen(id, shown), [mountScreen, id, shown]);\n const scope = React.useMemo(() => ({ id, store, context }), [id, store, context]);\n return <ScreenContext.Provider value={scope}>{children}</ScreenContext.Provider>;\n}\n",
|
|
8
|
+
"/** A screen's produce values, outside React state; read through useSyncExternalStore. */\nexport interface ScreenStore {\n get: (bindId: string, slot: string) => unknown;\n set: (bindId: string, slot: string, value: unknown) => void;\n subscribe: (listener: () => void) => () => void;\n}\n\nexport function createScreenStore(): ScreenStore {\n const values = new Map<string, unknown>();\n const listeners = new Set<() => void>();\n return {\n get: (b, s) => values.get(`${b}.${s}`),\n set(b, s, value) {\n const k = `${b}.${s}`;\n if (Object.is(values.get(k), value)) return;\n values.set(k, value);\n listeners.forEach(l => l());\n },\n subscribe(l) { listeners.add(l); return () => { listeners.delete(l); }; },\n };\n}\n",
|
|
9
|
+
"import * as React from \"react\";\nimport type { OperationConsumeBinding } from \"../framework/contract\";\nimport { evaluate, type Scope } from \"../framework/expr\";\nimport { BindingError, buildRequest, mapItems, requestKey, runSteps, select, type StepOutcome } from \"../framework/runner\";\nimport { useBindingRuntime, type BindingRuntime } from \"./BindingProvider\";\nimport { useScreen, type ScreenScope } from \"./BindingScreen\";\n\nfunction scopeOf(runtime: BindingRuntime, screen: ScreenScope, item?: unknown): Scope {\n return { slot: screen.store.get, context: screen.context, providers: runtime.providers(), transforms: runtime.transforms, item };\n}\n\n/** Publishes a produce slot's value. */\nexport function useProduce(bindId: string, slot: string, value: unknown): void {\n const { store } = useScreen();\n React.useEffect(() => { store.set(bindId, slot, value); }, [store, bindId, slot, value]);\n}\n\nexport type SlotStatus = \"unbound\" | \"waiting\" | \"loading\" | \"ready\" | \"error\";\nexport interface SlotResult<T> {\n status: SlotStatus;\n data: T | undefined;\n error: unknown;\n reload: () => void;\n}\n\nconst WAIT = \"\\u0000wait:\";\n\n/** Data for a consume slot. Subscribes to a request key, so it re-renders only when its own inputs change. */\nexport function useSlot<T = unknown>(bindId: string, slot: string): SlotResult<T> {\n const runtime = useBindingRuntime();\n const screen = useScreen();\n const binding = runtime.binding(screen.id, bindId, slot);\n const [nonce, setNonce] = React.useState(0);\n const [state, setState] = React.useState<{ key: string; status: SlotStatus; data?: T; error?: unknown }>({ key: \"\", status: \"loading\" });\n\n const snapshot = React.useCallback((): string => {\n if (!binding) return \"\";\n try {\n const scope = scopeOf(runtime, screen);\n if (binding.type === \"expression\") return JSON.stringify(evaluate(binding.value, scope) ?? null);\n if (binding.type !== \"operation\") return \"\";\n const op = runtime.operations.get(binding.operation);\n return op ? requestKey(buildRequest(op, binding.request, scope)) : WAIT + \"operation missing\";\n } catch (e) {\n return WAIT + (e instanceof Error ? e.message : String(e));\n }\n }, [binding, runtime, screen]);\n const key = React.useSyncExternalStore(screen.store.subscribe, snapshot, snapshot);\n\n React.useEffect(() => {\n if (!binding || binding.type !== \"operation\" || !key || key.startsWith(WAIT)) return;\n const op = runtime.operations.get(binding.operation)!;\n const scope = scopeOf(runtime, screen);\n const request = buildRequest(op, binding.request, scope);\n const k = requestKey(request);\n let live = true;\n setState(s => ({ key, status: \"loading\", data: s.data }));\n let p = nonce ? undefined : runtime.inflight.get(k);\n if (!p) {\n p = runtime.fetcher(request, op).finally(() => runtime.inflight.delete(k));\n runtime.inflight.set(k, p);\n }\n p.then(\n res => { if (live) setState({ key, status: \"ready\", data: mapItems(select(res, binding.select), binding as OperationConsumeBinding, scope) as T }); },\n error => { if (live) setState({ key, status: \"error\", error }); },\n );\n return () => { live = false; };\n }, [binding, key, nonce, runtime, screen]);\n\n const reload = React.useCallback(() => setNonce(n => n + 1), []);\n\n if (!binding || binding.type === \"steps\" || binding.type === \"none\") return { status: \"unbound\", data: undefined, error: undefined, reload };\n if (binding.type === \"expression\") return { status: \"ready\", data: (key ? JSON.parse(key) : undefined) as T, error: undefined, reload };\n if (key.startsWith(WAIT)) return { status: \"waiting\", data: undefined, error: new BindingError(key.slice(WAIT.length)), reload };\n return { status: state.key === key ? state.status : \"loading\", data: state.data, error: state.error, reload };\n}\n\n/** Resolver for a scoped slot (a cell) given its item. */\nexport function useCell<T = unknown>(bindId: string, slot: string): (item: unknown) => T | undefined {\n const runtime = useBindingRuntime();\n const screen = useScreen();\n const binding = runtime.binding(screen.id, bindId, slot);\n return React.useCallback(\n (item: unknown) => (binding?.type === \"expression\" ? (evaluate(binding.value, scopeOf(runtime, screen, item)) as T) : undefined),\n [binding, runtime, screen],\n );\n}\n\nexport interface TriggerHandle {\n /** False without a confirmed binding. */\n bound: boolean;\n running: boolean;\n /** Runs the slot's API calls; `item` is the row for row actions. */\n run: (item?: unknown) => Promise<StepOutcome[]>;\n}\n\nexport function useTrigger(bindId: string, slot: string): TriggerHandle {\n const runtime = useBindingRuntime();\n const screen = useScreen();\n const binding = runtime.binding(screen.id, bindId, slot);\n const [running, setRunning] = React.useState(false);\n const run = React.useCallback(async (item?: unknown) => {\n if (binding?.type !== \"steps\") return [];\n setRunning(true);\n try { return await runSteps(binding.steps, runtime.operations, scopeOf(runtime, screen, item), runtime.fetcher); }\n finally { setRunning(false); }\n }, [binding, runtime, screen]);\n return { bound: binding?.type === \"steps\" || binding?.type === \"none\", running, run };\n}\n"
|
|
10
|
+
],
|
|
11
|
+
"mappings": "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",
|
|
12
|
+
"debugId": "0D89B09671A8D81B64756E2164756E21",
|
|
13
|
+
"names": []
|
|
14
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { BindingManifest, Catalog, CatalogOperation, ContextProvider, PersistenceAdapter, ScreenId, SlotBinding, TransformDefinition } from "../framework/contract";
|
|
3
|
+
import type { Transforms } from "../framework/expr";
|
|
4
|
+
import type { Fetcher } from "../framework/runner";
|
|
5
|
+
export interface BindingRuntime {
|
|
6
|
+
operations: Map<string, CatalogOperation>;
|
|
7
|
+
/** Confirmed bindings only, indexed "screen|component|slot". Drafts never run. */
|
|
8
|
+
binding: (screen: ScreenId, component: string, slot: string) => SlotBinding | undefined;
|
|
9
|
+
fetcher: Fetcher;
|
|
10
|
+
transforms: Transforms;
|
|
11
|
+
providers: () => Record<string, unknown>;
|
|
12
|
+
/** In-flight requests by key, shared across slots. */
|
|
13
|
+
inflight: Map<string, Promise<unknown>>;
|
|
14
|
+
persistence?: PersistenceAdapter;
|
|
15
|
+
/** Loads the studio-saved manifest for a screen; no-op without persistence. */
|
|
16
|
+
loadSaved: (screen: ScreenId) => void;
|
|
17
|
+
/** Reloads saved manifests for mounted screens (after the studio closes). */
|
|
18
|
+
reloadSaved: () => void;
|
|
19
|
+
/** Registers a mounted screen and whether it is shown; returns the unregister function. */
|
|
20
|
+
mountScreen: (screen: ScreenId, shown: boolean) => () => void;
|
|
21
|
+
/** The shown screen that was shown most recently (an open dialog wins over its page). */
|
|
22
|
+
activeScreen: () => ScreenId | undefined;
|
|
23
|
+
}
|
|
24
|
+
export interface BindingProviderProps {
|
|
25
|
+
catalog: Catalog;
|
|
26
|
+
/** Manifests committed with the app. */
|
|
27
|
+
manifests: BindingManifest[];
|
|
28
|
+
/** Sends requests (base URL, auth, errors). */
|
|
29
|
+
fetcher: Fetcher;
|
|
30
|
+
transforms?: TransformDefinition[];
|
|
31
|
+
providers?: ContextProvider[];
|
|
32
|
+
/** Design time only: studio-saved manifests override committed ones. */
|
|
33
|
+
persistence?: PersistenceAdapter;
|
|
34
|
+
children: React.ReactNode;
|
|
35
|
+
}
|
|
36
|
+
export declare function latestShown(screens: Iterable<{
|
|
37
|
+
screen: ScreenId;
|
|
38
|
+
shown: boolean;
|
|
39
|
+
at: number;
|
|
40
|
+
}>): ScreenId | undefined;
|
|
41
|
+
export declare function useBindingRuntime(): BindingRuntime;
|
|
42
|
+
export declare function BindingProvider({ catalog, manifests, fetcher, transforms, providers, persistence, children }: BindingProviderProps): React.JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { ScreenId } from "../framework/contract";
|
|
3
|
+
import { type ScreenStore } from "./screenStore";
|
|
4
|
+
export interface ScreenScope {
|
|
5
|
+
id: ScreenId;
|
|
6
|
+
store: ScreenStore;
|
|
7
|
+
/** Values passed in, keyed by the registry entry's `context` ids. */
|
|
8
|
+
context: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
export declare function useScreen(): ScreenScope;
|
|
11
|
+
/** Marks a subtree that stays mounted while hidden (inactive tabs, cached views). */
|
|
12
|
+
export declare function BindingActive({ value, children }: {
|
|
13
|
+
value: boolean;
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
}): React.JSX.Element;
|
|
16
|
+
export interface BindingScreenProps {
|
|
17
|
+
/** The screen's id in the registry. */
|
|
18
|
+
id: ScreenId;
|
|
19
|
+
context?: Record<string, unknown>;
|
|
20
|
+
children: React.ReactNode;
|
|
21
|
+
}
|
|
22
|
+
/** Binding scope for one screen: its produce values and context. */
|
|
23
|
+
export declare function BindingScreen({ id, context, children }: BindingScreenProps): React.JSX.Element;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type StepOutcome } from "../framework/runner";
|
|
2
|
+
/** Publishes a produce slot's value. */
|
|
3
|
+
export declare function useProduce(bindId: string, slot: string, value: unknown): void;
|
|
4
|
+
export type SlotStatus = "unbound" | "waiting" | "loading" | "ready" | "error";
|
|
5
|
+
export interface SlotResult<T> {
|
|
6
|
+
status: SlotStatus;
|
|
7
|
+
data: T | undefined;
|
|
8
|
+
error: unknown;
|
|
9
|
+
reload: () => void;
|
|
10
|
+
}
|
|
11
|
+
/** Data for a consume slot. Subscribes to a request key, so it re-renders only when its own inputs change. */
|
|
12
|
+
export declare function useSlot<T = unknown>(bindId: string, slot: string): SlotResult<T>;
|
|
13
|
+
/** Resolver for a scoped slot (a cell) given its item. */
|
|
14
|
+
export declare function useCell<T = unknown>(bindId: string, slot: string): (item: unknown) => T | undefined;
|
|
15
|
+
export interface TriggerHandle {
|
|
16
|
+
/** False without a confirmed binding. */
|
|
17
|
+
bound: boolean;
|
|
18
|
+
running: boolean;
|
|
19
|
+
/** Runs the slot's API calls; `item` is the row for row actions. */
|
|
20
|
+
run: (item?: unknown) => Promise<StepOutcome[]>;
|
|
21
|
+
}
|
|
22
|
+
export declare function useTrigger(bindId: string, slot: string): TriggerHandle;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** A screen's produce values, outside React state; read through useSyncExternalStore. */
|
|
2
|
+
export interface ScreenStore {
|
|
3
|
+
get: (bindId: string, slot: string) => unknown;
|
|
4
|
+
set: (bindId: string, slot: string, value: unknown) => void;
|
|
5
|
+
subscribe: (listener: () => void) => () => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function createScreenStore(): ScreenStore;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { Engine, OpView, Ranked } from "../framework/engine";
|
|
3
|
+
export declare const opTitle: (v: OpView) => string;
|
|
4
|
+
export declare function MethodTag({ method }: {
|
|
5
|
+
method: string;
|
|
6
|
+
}): React.JSX.Element;
|
|
7
|
+
/** Searchable list of every documented operation, best matches first. */
|
|
8
|
+
export declare function ApiPicker({ engine, ranked, value, onPick, label, autoOpen }: {
|
|
9
|
+
engine: Engine;
|
|
10
|
+
ranked: () => Ranked[];
|
|
11
|
+
value?: string;
|
|
12
|
+
onPick: (id: string) => void;
|
|
13
|
+
label?: string;
|
|
14
|
+
autoOpen?: boolean;
|
|
15
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { Catalog, PersistenceAdapter, ScreenId } from "../framework/contract";
|
|
3
|
+
import { type FrameworkData } from "../framework/engine";
|
|
4
|
+
import "./studio.css";
|
|
5
|
+
export interface BindingStudioProps {
|
|
6
|
+
/** Descriptors, registry and extension points. `catalog` is optional: without it the studio reads the docs URL. */
|
|
7
|
+
framework: Omit<FrameworkData, "catalog"> & {
|
|
8
|
+
catalog?: Catalog;
|
|
9
|
+
};
|
|
10
|
+
/** Default docs URL; each user can change it in Settings. */
|
|
11
|
+
docsUrl?: string;
|
|
12
|
+
/** Where manifests are kept. Defaults to the browser's local storage. */
|
|
13
|
+
persistence?: PersistenceAdapter;
|
|
14
|
+
/** Screen to open first. */
|
|
15
|
+
initialScreen?: ScreenId;
|
|
16
|
+
/** Shown in the top bar. */
|
|
17
|
+
title?: string;
|
|
18
|
+
/** Shows a close button in the top bar. */
|
|
19
|
+
onClose?: () => void;
|
|
20
|
+
}
|
|
21
|
+
export declare function BindingStudio({ framework, docsUrl, persistence, initialScreen, title, onClose }: BindingStudioProps): React.JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type BindingStudioProps } from "./BindingStudio";
|
|
3
|
+
import "./studio.css";
|
|
4
|
+
export type BindingWidgetProps = Pick<BindingStudioProps, "framework" | "docsUrl" | "title">;
|
|
5
|
+
/**
|
|
6
|
+
* Floating button that opens the studio over the app, on the screen currently shown.
|
|
7
|
+
* Render it inside <BindingProvider>, in design mode only. Edits apply to the app when it closes.
|
|
8
|
+
*/
|
|
9
|
+
export declare function BindingWidget({ framework, docsUrl, title }: BindingWidgetProps): React.JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { ScreenEntry } from "../framework/contract";
|
|
3
|
+
import type { Engine } from "../framework/engine";
|
|
4
|
+
/** A screen's components as a tree, filterable to unconnected ones. */
|
|
5
|
+
export declare function ComponentList({ engine, screen, selected, onSelect }: {
|
|
6
|
+
engine: Engine;
|
|
7
|
+
screen: ScreenEntry;
|
|
8
|
+
selected?: string;
|
|
9
|
+
onSelect: (id: string) => void;
|
|
10
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { ScreenId } from "../framework/contract";
|
|
3
|
+
import type { Engine } from "../framework/engine";
|
|
4
|
+
export declare function FindAnything({ engine, onGo }: {
|
|
5
|
+
engine: Engine;
|
|
6
|
+
onGo: (screen: ScreenId, comp?: string) => void;
|
|
7
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ComponentInstance, ScreenEntry, SlotBinding } from "../framework/contract";
|
|
2
|
+
import type { Engine } from "../framework/engine";
|
|
3
|
+
/** Settings for one component: a card per bindable slot. */
|
|
4
|
+
export declare function Inspector({ engine, screen, comp, put, drop, goTo, onClose }: {
|
|
5
|
+
engine: Engine;
|
|
6
|
+
screen: ScreenEntry;
|
|
7
|
+
comp: ComponentInstance;
|
|
8
|
+
put: (b: SlotBinding) => void;
|
|
9
|
+
drop: (c: string, s: string) => void;
|
|
10
|
+
goTo: (id: string) => void;
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { ScreenEntry, ScreenId } from "../framework/contract";
|
|
3
|
+
import type { Engine } from "../framework/engine";
|
|
4
|
+
/** Screens grouped by path: product, then groups. */
|
|
5
|
+
export type NavNode = {
|
|
6
|
+
key: string;
|
|
7
|
+
name: string;
|
|
8
|
+
nodes: NavNode[];
|
|
9
|
+
screens: ScreenEntry[];
|
|
10
|
+
all: ScreenEntry[];
|
|
11
|
+
};
|
|
12
|
+
export declare function buildTree(screens: ScreenEntry[]): NavNode[];
|
|
13
|
+
export declare function Navigator({ engine, current, onPick }: {
|
|
14
|
+
engine: Engine;
|
|
15
|
+
current: ScreenId;
|
|
16
|
+
onPick: (id: ScreenId) => void;
|
|
17
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { BindingManifest } from "../framework/contract";
|
|
3
|
+
import type { CatalogState } from "./useCatalog";
|
|
4
|
+
export interface SettingsPanelProps {
|
|
5
|
+
docsUrl: string;
|
|
6
|
+
onDocsUrl: (url: string) => void;
|
|
7
|
+
catalog: CatalogState;
|
|
8
|
+
onReload: () => void;
|
|
9
|
+
/** Every screen's current manifest, for download. */
|
|
10
|
+
manifests: () => BindingManifest[];
|
|
11
|
+
onImport: (manifests: BindingManifest[]) => void;
|
|
12
|
+
onClose: () => void;
|
|
13
|
+
}
|
|
14
|
+
/** Studio settings: where the API docs come from, and moving bindings in and out as files. */
|
|
15
|
+
export declare function SettingsPanel({ docsUrl, onDocsUrl, catalog, onReload, manifests, onImport, onClose }: SettingsPanelProps): React.JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export interface Placement {
|
|
3
|
+
top: number;
|
|
4
|
+
left: number;
|
|
5
|
+
side: "top" | "bottom";
|
|
6
|
+
}
|
|
7
|
+
/** Above the anchor when it fits, otherwise below; horizontally centred and kept inside the viewport. */
|
|
8
|
+
export declare function placeTip(anchor: {
|
|
9
|
+
top: number;
|
|
10
|
+
bottom: number;
|
|
11
|
+
left: number;
|
|
12
|
+
width: number;
|
|
13
|
+
}, tip: {
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
}, viewport: {
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
}, gap?: number, margin?: number): Placement;
|
|
20
|
+
/** Info button with a tooltip on hover and keyboard focus. Rendered in the top layer, so no container clips it. */
|
|
21
|
+
export declare function Tip({ text }: {
|
|
22
|
+
text: string;
|
|
23
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { Engine, OpView, Source } from "../../framework/engine";
|
|
3
|
+
/** Request fields of an operation, required first. Optional ones fold away. */
|
|
4
|
+
export declare function RequestInputs({ engine, view, request, sources, onChange, idp }: {
|
|
5
|
+
engine: Engine;
|
|
6
|
+
view: OpView;
|
|
7
|
+
request: Record<string, string>;
|
|
8
|
+
sources: Source[];
|
|
9
|
+
onChange: (r: Record<string, string>) => void;
|
|
10
|
+
idp: string;
|
|
11
|
+
}): React.JSX.Element | null;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Engine, Source } from "../../framework/engine";
|
|
2
|
+
/** Picker for one value: every value on the screen that fits the target type, grouped by where it comes from. */
|
|
3
|
+
export declare function SourceSelect({ engine, value, type, sources, onChange, id }: {
|
|
4
|
+
engine: Engine;
|
|
5
|
+
value?: string;
|
|
6
|
+
type: string;
|
|
7
|
+
sources: Source[];
|
|
8
|
+
onChange: (v: string | undefined) => void;
|
|
9
|
+
id: string;
|
|
10
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { Step } from "../../framework/contract";
|
|
3
|
+
import type { EditorProps } from "./types";
|
|
4
|
+
/** One API call in a trigger: which API, whether it runs per item, and what it sends. */
|
|
5
|
+
export declare function StepCard({ engine, screen, comp, slot, step, index, total, onChange, onRemove, onMove }: EditorProps & {
|
|
6
|
+
step: Step;
|
|
7
|
+
index: number;
|
|
8
|
+
total: number;
|
|
9
|
+
onChange: (s: Step) => void;
|
|
10
|
+
onRemove: () => void;
|
|
11
|
+
onMove: (d: -1 | 1) => void;
|
|
12
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ComponentInstance, ScreenId, SlotBinding, SlotDescriptor } from "../../framework/contract";
|
|
2
|
+
import type { Engine, Source } from "../../framework/engine";
|
|
3
|
+
/** Props shared by slot editors. */
|
|
4
|
+
export interface EditorProps {
|
|
5
|
+
engine: Engine;
|
|
6
|
+
screen: ScreenId;
|
|
7
|
+
comp: ComponentInstance;
|
|
8
|
+
slot: SlotDescriptor;
|
|
9
|
+
put: (b: SlotBinding) => void;
|
|
10
|
+
drop: () => void;
|
|
11
|
+
goTo: (bindId: string) => void;
|
|
12
|
+
}
|
|
13
|
+
/** How each source group is named in value pickers. */
|
|
14
|
+
export declare const GROUP_LABEL: Record<Source["group"], string>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
declare const paths: {
|
|
3
|
+
search: React.JSX.Element;
|
|
4
|
+
check: React.JSX.Element;
|
|
5
|
+
bound: React.JSX.Element;
|
|
6
|
+
suggested: React.JSX.Element;
|
|
7
|
+
partial: React.JSX.Element;
|
|
8
|
+
unbound: React.JSX.Element;
|
|
9
|
+
data: React.JSX.Element;
|
|
10
|
+
action: React.JSX.Element;
|
|
11
|
+
row: React.JSX.Element;
|
|
12
|
+
plus: React.JSX.Element;
|
|
13
|
+
chevronRight: React.JSX.Element;
|
|
14
|
+
chevronDown: React.JSX.Element;
|
|
15
|
+
close: React.JSX.Element;
|
|
16
|
+
screen: React.JSX.Element;
|
|
17
|
+
dialog: React.JSX.Element;
|
|
18
|
+
api: React.JSX.Element;
|
|
19
|
+
trash: React.JSX.Element;
|
|
20
|
+
link: React.JSX.Element;
|
|
21
|
+
repeat: React.JSX.Element;
|
|
22
|
+
arrowLeft: React.JSX.Element;
|
|
23
|
+
component: React.JSX.Element;
|
|
24
|
+
pointer: React.JSX.Element;
|
|
25
|
+
refresh: React.JSX.Element;
|
|
26
|
+
list: React.JSX.Element;
|
|
27
|
+
todo: React.JSX.Element;
|
|
28
|
+
target: React.JSX.Element;
|
|
29
|
+
apply: React.JSX.Element;
|
|
30
|
+
info: React.JSX.Element;
|
|
31
|
+
settings: React.JSX.Element;
|
|
32
|
+
download: React.JSX.Element;
|
|
33
|
+
upload: React.JSX.Element;
|
|
34
|
+
alert: React.JSX.Element;
|
|
35
|
+
};
|
|
36
|
+
export type IconName = keyof typeof paths;
|
|
37
|
+
export declare function Icon({ name, size, className }: {
|
|
38
|
+
name: IconName;
|
|
39
|
+
size?: number;
|
|
40
|
+
className?: string;
|
|
41
|
+
}): React.JSX.Element;
|
|
42
|
+
/** Descriptor SVG drawn as a CSS mask: follows currentColor and is never parsed as markup. */
|
|
43
|
+
export declare function KindIcon({ svg }: {
|
|
44
|
+
svg?: string;
|
|
45
|
+
}): React.JSX.Element;
|
|
46
|
+
declare const STATE_LABEL: {
|
|
47
|
+
readonly bound: "Connected";
|
|
48
|
+
readonly suggested: "Needs review";
|
|
49
|
+
readonly partial: "Partly connected";
|
|
50
|
+
readonly unbound: "Not connected";
|
|
51
|
+
};
|
|
52
|
+
export type StateName = keyof typeof STATE_LABEL;
|
|
53
|
+
export declare const stateLabel: (s: StateName) => "Connected" | "Needs review" | "Partly connected" | "Not connected";
|
|
54
|
+
export declare function StateIcon({ state, size }: {
|
|
55
|
+
state: StateName;
|
|
56
|
+
size?: number;
|
|
57
|
+
}): React.JSX.Element;
|
|
58
|
+
/** Circular progress. */
|
|
59
|
+
export declare function Ring({ done, total, size, stroke }: {
|
|
60
|
+
done: number;
|
|
61
|
+
total: number;
|
|
62
|
+
size?: number;
|
|
63
|
+
stroke?: number;
|
|
64
|
+
}): React.JSX.Element;
|
|
65
|
+
export {};
|