Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .changeset/compiler-fallback-loop-tools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
"@stackables/bridge": patch
"@stackables/bridge-core": patch
"@stackables/bridge-compiler": patch
"@stackables/bridge-parser": patch
---

Add memoized tool handles with compiler support.

Bridge `with` declarations now support `memoize` for tool handles, including
loop-scoped tool handles inside array mappings. Memoized handles reuse the same
result for repeated calls with identical inputs, and each declared handle keeps
its own cache.

The AOT compiler now compiles memoized tool handles too, including loop-scoped
tool handles inside array mappings. Compiled execution preserves request-scoped
caching semantics and reuses results for repeated calls with identical inputs.
10 changes: 10 additions & 0 deletions .changeset/compiler-shadowed-loop-tools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@stackables/bridge-compiler": patch
---

Compile shadowed loop-scoped tool handles in the AOT compiler.

Bridges can now redeclare the same tool alias in nested array scopes without
triggering `BridgeCompilerIncompatibleError` or falling back to the interpreter.
The compiler now assigns distinct tool instances to repeated handle bindings so
each nested scope emits and reads from the correct tool call.
12 changes: 12 additions & 0 deletions .changeset/strict-scope-rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@stackables/bridge": patch
"@stackables/bridge-core": patch
"@stackables/bridge-compiler": patch
"@stackables/bridge-parser": patch
---

Fix strict nested scope resolution for array mappings.

Nested scopes can now read iterator aliases from visible parent scopes while
still resolving overlapping names to the nearest inner scope. This also keeps
invalid nested tool input wiring rejected during parsing.
21 changes: 14 additions & 7 deletions docs/fuzz-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ Bridge uses [fast-check](https://github.com/dubzzz/fast-check) (^4.5.3) for prop

### Test files

| File | Package | Purpose |
| ------------------------------------ | ----------------- | ------------------------------------------------------------------- |
| `test/fuzz-compile.test.ts` | `bridge-compiler` | JS syntax validity, determinism, flat-path AOT/runtime parity |
| `test/fuzz-runtime-parity.test.ts` | `bridge-compiler` | Deep-path parity, array mapping parity, tool-call timeout parity |
| `test/fuzz-regressions.todo.test.ts` | `bridge-compiler` | Backlog of known fuzz-discovered divergences as `test.todo` entries |
| `test/fuzz-stdlib.test.ts` | `bridge-stdlib` | Array and string tool crash-safety |
| `test/fuzz-parser.test.ts` | `bridge` | Parser crash-safety, serializer round-trip, formatter stability |
| File | Package | Purpose |
| ------------------------------------ | ----------------- | ----------------------------------------------------------------------------------------------- |
| `test/fuzz-compile.test.ts` | `bridge-compiler` | JS syntax validity, determinism, flat-path AOT/runtime parity |
| `test/fuzz-runtime-parity.test.ts` | `bridge-compiler` | Deep-path parity, array mapping parity, loop-tool parity and fallback, tool-call timeout parity |
| `test/fuzz-regressions.todo.test.ts` | `bridge-compiler` | Backlog of known fuzz-discovered divergences as `test.todo` entries |
| `test/fuzz-stdlib.test.ts` | `bridge-stdlib` | Array and string tool crash-safety |
| `test/fuzz-parser.test.ts` | `bridge` | Parser crash-safety, serializer round-trip, formatter stability, loop-scoped tool syntax |

---

Expand All @@ -27,18 +27,22 @@ Bridge uses [fast-check](https://github.com/dubzzz/fast-check) (^4.5.3) for prop
- AOT/runtime parity on flat single-segment paths (`fc.jsonValue()` inputs)
- AOT/runtime parity on deep multi-segment paths with chaotic inputs (`NaN`, `Infinity`, `-0`, `undefined`, deeply nested objects)
- AOT/runtime parity on array-mapping bridges (`[] as el { ... }`) with chaotic element data
- AOT/runtime parity on compiler-compatible loop-scoped tool bridges
- Fallback parity for compiler-incompatible loop-scoped tool bridges that use nested loop-local tools, memoized handles, or shadowed loop-local tool aliases
- AOT/runtime parity on tool-call timeout (`BridgeTimeoutError` class and message match)
- Parser round-trip: text → parse → serialize → reparse → execute parity
- `parseBridge` never throws unstructured errors on random input
- `parseBridgeDiagnostics` never throws (LSP/IDE safety)
- `prettyPrintToSource` idempotence and output parseability (bridge, tool, const blocks)
- `prettyPrintToSource` stability for loop-scoped `with ... memoize` declarations inside array mappings, plus `serializeBridge` round-trip coverage for non-shadowed loop-scoped handles
- `arr.filter`, `arr.find`, `arr.first`, `arr.toArray` crash-safety on any input type
- `str.toLowerCase`, `str.toUpperCase`, `str.trim`, `str.length` crash-safety on any input type

### Known gaps (P3)

- `Symbol`, `BigInt`, circular-ref handling across all stdlib tools
- `parseBridgeDiagnostics` completeness: valid input should produce zero error-severity diagnostics
- Randomized fallback/nullish edge cases for every compiler-incompatible shape beyond loop-scoped tool handles

---

Expand All @@ -48,6 +52,8 @@ Bridge uses [fast-check](https://github.com/dubzzz/fast-check) (^4.5.3) for prop
| ---------------------------------------------------- | ----- |
| Deep-path AOT/runtime parity | 3,000 |
| Array mapping parity | 1,000 |
| Loop-scoped tool AOT/runtime parity | 400 |
| Loop-scoped tool fallback parity | 300 |
| Tool-call timeout parity | 500 |
| `parseBridge` never panics | 5,000 |
| `parseBridgeDiagnostics` never throws | 5,000 |
Expand All @@ -56,6 +62,7 @@ Bridge uses [fast-check](https://github.com/dubzzz/fast-check) (^4.5.3) for prop
| `prettyPrintToSource` parseability (basic) | 2,000 |
| `prettyPrintToSource` idempotence (extended blocks) | 1,000 |
| `prettyPrintToSource` parseability (extended blocks) | 1,000 |
| Loop-scoped tool round-trip / formatter properties | 1,000 |
| stdlib tool crash-safety (per tool) | 2,000 |

---
Expand Down
15 changes: 15 additions & 0 deletions packages/bridge-compiler/src/bridge-asserts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { Bridge } from "@stackables/bridge-core";

export class BridgeCompilerIncompatibleError extends Error {
constructor(
public readonly operation: string,
message: string,
) {
super(message);
this.name = "BridgeCompilerIncompatibleError";
}
}

export function assertBridgeCompilerCompatible(_bridge: Bridge): void {
// Intentionally empty: all currently supported bridge constructs compile.
}
Loading
Loading