@stackables/bridge-core 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Stackables
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,212 @@
1
+ import type { Bridge, Instruction, NodeRef, ToolMap, Wire } from "./types.ts";
2
+ /** Fatal panic error — bypasses all error boundaries (`?.` and `catch`). */
3
+ export declare class BridgePanicError extends Error {
4
+ constructor(message: string);
5
+ }
6
+ /** Abort error — raised when an external AbortSignal cancels execution. */
7
+ export declare class BridgeAbortError extends Error {
8
+ constructor(message?: string);
9
+ }
10
+ /**
11
+ * Structured logger interface for Bridge engine events.
12
+ * Accepts any compatible logger: pino, winston, bunyan, `console`, etc.
13
+ * All methods default to silent no-ops when no logger is provided.
14
+ */
15
+ export interface Logger {
16
+ debug?: (...args: any[]) => void;
17
+ info?: (...args: any[]) => void;
18
+ warn?: (...args: any[]) => void;
19
+ error?: (...args: any[]) => void;
20
+ }
21
+ /** Matches graphql's internal Path type (not part of the public exports map) */
22
+ interface Path {
23
+ readonly prev: Path | undefined;
24
+ readonly key: string | number;
25
+ readonly typename: string | undefined;
26
+ }
27
+ type Trunk = {
28
+ module: string;
29
+ type: string;
30
+ field: string;
31
+ instance?: number;
32
+ };
33
+ /** Trace verbosity level.
34
+ * - `"off"` (default) — no collection, zero overhead
35
+ * - `"basic"` — tool, fn, timing, errors; no input/output
36
+ * - `"full"` — everything including input and output */
37
+ export type TraceLevel = "basic" | "full" | "off";
38
+ /** A single recorded tool invocation. */
39
+ export type ToolTrace = {
40
+ /** Tool name as resolved (e.g. "hereGeo", "std.str.toUpperCase") */
41
+ tool: string;
42
+ /** The function that was called (e.g. "httpCall", "upperCase") */
43
+ fn: string;
44
+ /** Input object passed to the tool function (only in "full" level) */
45
+ input?: Record<string, any>;
46
+ /** Resolved output (only in "full" level, on success) */
47
+ output?: any;
48
+ /** Error message (present when the tool threw) */
49
+ error?: string;
50
+ /** Wall-clock duration in milliseconds */
51
+ durationMs: number;
52
+ /** Monotonic timestamp (ms) relative to the first trace in the request */
53
+ startedAt: number;
54
+ };
55
+ /** Shared trace collector — one per request, passed through the tree. */
56
+ export declare class TraceCollector {
57
+ readonly traces: ToolTrace[];
58
+ readonly level: "basic" | "full";
59
+ private readonly epoch;
60
+ constructor(level?: "basic" | "full");
61
+ /** Returns ms since the collector was created */
62
+ now(): number;
63
+ record(trace: ToolTrace): void;
64
+ /** Build a trace entry, omitting input/output for basic level. */
65
+ entry(base: {
66
+ tool: string;
67
+ fn: string;
68
+ startedAt: number;
69
+ durationMs: number;
70
+ input?: Record<string, any>;
71
+ output?: any;
72
+ error?: string;
73
+ }): ToolTrace;
74
+ }
75
+ export declare class ExecutionTree {
76
+ trunk: Trunk;
77
+ private instructions;
78
+ private context?;
79
+ private parent?;
80
+ state: Record<string, any>;
81
+ bridge: Bridge | undefined;
82
+ private toolDepCache;
83
+ private toolDefCache;
84
+ private pipeHandleMap;
85
+ /** Promise that resolves when all critical `force` handles have settled. */
86
+ private forcedExecution?;
87
+ /** Shared trace collector — present only when tracing is enabled. */
88
+ tracer?: TraceCollector;
89
+ /** Structured logger passed from BridgeOptions. Defaults to no-ops. */
90
+ logger?: Logger;
91
+ /** External abort signal — cancels execution when triggered. */
92
+ signal?: AbortSignal;
93
+ private toolFns?;
94
+ constructor(trunk: Trunk, instructions: Instruction[], toolFns?: ToolMap, context?: Record<string, any> | undefined, parent?: ExecutionTree | undefined);
95
+ /** Derive tool name from a trunk */
96
+ private getToolName;
97
+ /** Deep-lookup a tool function by dotted name (e.g. "std.str.toUpperCase").
98
+ * Falls back to a flat key lookup for backward compat (e.g. "hereapi.geocode" as literal key). */
99
+ private lookupToolFn;
100
+ /** Resolve a ToolDef by name, merging the extends chain (cached) */
101
+ private resolveToolDefByName;
102
+ /** Resolve a tool definition's wires into a nested input object */
103
+ private resolveToolWires;
104
+ /** Resolve a source reference from a tool wire against its dependencies */
105
+ private resolveToolSource;
106
+ /** Call a tool dependency (cached per request) */
107
+ private resolveToolDep;
108
+ schedule(target: Trunk): any;
109
+ /**
110
+ * Invoke a tool function, recording both an OpenTelemetry span and (when
111
+ * tracing is enabled) a ToolTrace entry. All three tool-call sites in the
112
+ * engine delegate here so instrumentation lives in exactly one place.
113
+ */
114
+ private callTool;
115
+ shadow(): ExecutionTree;
116
+ /** Returns collected traces (empty array when tracing is disabled). */
117
+ getTraces(): ToolTrace[];
118
+ private pullSingle;
119
+ pull(refs: NodeRef[]): Promise<any>;
120
+ /**
121
+ * Safe execution pull: wraps individual safe-flagged pulls in try/catch.
122
+ * Wires with `safe: true` swallow errors and return undefined.
123
+ * Non-safe wires propagate errors normally.
124
+ */
125
+ pullSafe(pulls: Extract<Wire, {
126
+ from: NodeRef;
127
+ }>[]): Promise<any>;
128
+ push(args: Record<string, any>): void;
129
+ /** Store the aggregated promise for critical forced handles so
130
+ * `response()` can await it exactly once per bridge execution. */
131
+ setForcedExecution(p: Promise<void>): void;
132
+ /** Return the critical forced-execution promise (if any). */
133
+ getForcedExecution(): Promise<void> | undefined;
134
+ /**
135
+ * Eagerly schedule tools targeted by `force <handle>` statements.
136
+ *
137
+ * Returns an array of promises for **critical** forced handles (those
138
+ * without `?? null`). Fire-and-forget handles (`catchError: true`) are
139
+ * scheduled but their errors are silently suppressed.
140
+ *
141
+ * Callers must `await Promise.all(...)` the returned promises so that a
142
+ * critical force failure propagates as a standard error.
143
+ */
144
+ executeForced(): Promise<any>[];
145
+ /**
146
+ * Resolve a set of matched wires.
147
+ *
148
+ * Architecture: two distinct resolution axes —
149
+ *
150
+ * **Falsy Gate** (`||`, within a wire): `falsyFallbackRefs` + `falsyFallback`
151
+ * → truthy check — falsy values (0, "", false) trigger fallback chain.
152
+ *
153
+ * **Overdefinition** (across wires): multiple wires target the same path
154
+ * → nullish check — only null/undefined falls through to the next wire.
155
+ *
156
+ * Per-wire layers:
157
+ * Layer 1 — Execution (pullSingle + safe modifier)
158
+ * Layer 2a — Falsy Gate (falsyFallbackRefs → falsyFallback / falsyControl)
159
+ * Layer 2b — Nullish Gate (nullishFallbackRef / nullishFallback / nullishControl)
160
+ * Layer 3 — Catch (catchFallbackRef / catchFallback / catchControl)
161
+ *
162
+ * After layers 1–2b, the overdefinition boundary (`!= null`) decides whether
163
+ * to return or continue to the next wire.
164
+ */
165
+ private resolveWires;
166
+ /**
167
+ * Resolve an output field by path for use outside of a GraphQL resolver.
168
+ *
169
+ * This is the non-GraphQL equivalent of what `response()` does per field:
170
+ * it finds all wires targeting `this.trunk` at `path` and resolves them.
171
+ *
172
+ * Used by `executeBridge()` so standalone bridge execution does not need to
173
+ * fabricate GraphQL Path objects to pull output data.
174
+ *
175
+ * @param path - Output field path, e.g. `["lat"]`. Pass `[]` for whole-output
176
+ * array bridges (`o <- items[] as x { ... }`).
177
+ * @param array - When `true` and the result is an array, wraps each element
178
+ * in a shadow tree (mirrors `response()` array handling).
179
+ */
180
+ pullOutputField(path: string[], array?: boolean): Promise<unknown>;
181
+ /**
182
+ * Execute the bridge end-to-end without GraphQL.
183
+ *
184
+ * Injects `input` as the trunk arguments, runs forced wires, then pulls
185
+ * and materialises every output field into a plain JS object (or array of
186
+ * objects for array-mapped bridges).
187
+ *
188
+ * This is the single entry-point used by `executeBridge()`.
189
+ */
190
+ run(input: Record<string, unknown>): Promise<unknown>;
191
+ /**
192
+ * Recursively convert shadow trees into plain JS objects.
193
+ *
194
+ * Wire categories at each level (prefix = P):
195
+ * Leaf — `to.path = [...P, name]`, no deeper paths → scalar
196
+ * Array — direct wire AND deeper paths → pull as array, recurse
197
+ * Nested object — only deeper paths, no direct wire → pull each
198
+ * full path and assemble via setNested
199
+ */
200
+ private materializeShadows;
201
+ response(ipath: Path, array: boolean): Promise<any>;
202
+ /**
203
+ * Find define output wires for a specific field path.
204
+ *
205
+ * Looks for whole-object define forward wires (`o <- defineHandle`)
206
+ * at path=[] for this trunk, then searches the define's output wires
207
+ * for ones matching the requested field path.
208
+ */
209
+ private findDefineFieldWires;
210
+ }
211
+ export {};
212
+ //# sourceMappingURL=ExecutionTree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExecutionTree.d.ts","sourceRoot":"","sources":["../src/ExecutionTree.ts"],"names":[],"mappings":"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"}