Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
44cc4d3
initial step of refactoring builder API to be created by a factory + …
seefeldb Jun 6, 2025
8c4f7fa
deno.lock change, not sure this is right
seefeldb Jun 6, 2025
2a712d9
let's just go back to `any` here, this is wonky
seefeldb Jun 6, 2025
2ac3fe2
builder/interface.ts and builder/schema-to-ts.ts are now together ent…
seefeldb Jun 6, 2025
27de921
lots of types fixes for previous change
seefeldb Jun 6, 2025
d8837ba
more type fixes
seefeldb Jun 6, 2025
14b319b
remove this syntax for now
seefeldb Jun 6, 2025
82ca353
remove extraneous parameter for createBuilder
seefeldb Jun 6, 2025
9c614de
add back ability to set schema with cell/opaqueRef
seefeldb Jun 7, 2025
f2fe26a
fix more tests
seefeldb Jun 7, 2025
79ef937
export opaqueRef directly still, for internal use outside of recipes
seefeldb Jun 7, 2025
6074063
partially fix test
seefeldb Jun 7, 2025
c630bc1
import type with `type` annotation
seefeldb Jun 9, 2025
6f97b4d
interface is now truly just the public interface. users should only i…
seefeldb Jun 9, 2025
d6398e3
separated imports in other places
seefeldb Jun 9, 2025
4d9e789
fix misaligned exports
seefeldb Jun 9, 2025
f11897e
removed Mutable from interface
seefeldb Jun 9, 2025
255a1cb
change all recipes to import from /interface.
seefeldb Jun 9, 2025
70139fe
redo use of SchemaWithoutCell in the right places, this fixed the tests
seefeldb Jun 9, 2025
0206774
need Mutable<> after all, so duplicating here to keep interface.ts an…
seefeldb Jun 9, 2025
fe6edc7
recipe also needs SchemaWithoutCell
seefeldb Jun 9, 2025
65c14ca
and recipe needs that also for the recipe function!
seefeldb Jun 9, 2025
1300446
fix recipes
seefeldb Jun 9, 2025
2a226d6
move getRecipeEnvironment to public environment
seefeldb Jun 9, 2025
5c4f4b7
revert to original deno.lock
seefeldb Jun 9, 2025
2bb1e50
also exports constants via builder!
seefeldb Jun 9, 2025
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
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ The instructions in this document apply to the entire repository.
- Prefer named exports over default exports.
- Use package names for internal imports.
- Destructure when importing multiple names from the same module.
- Import either from `@commontools/builder` (internal API) or
`@commontools/builder/interface` (external API), but not both.

### Error Handling

Expand Down
5 changes: 4 additions & 1 deletion packages/builder/deno.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"name": "@commontools/builder",
"exports": "./src/index.ts",
"exports": {
".": "./src/index.ts",
"./interface": "./src/interface.ts"
},
"tasks": {
"test": "deno test --allow-env"
}
Expand Down
11 changes: 8 additions & 3 deletions packages/builder/src/built-in.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { createNodeFactory, lift } from "./module.ts";
import { type Cell } from "@commontools/runner";
import type { JSONSchema, NodeFactory, Opaque, OpaqueRef } from "./types.ts";
import type { Schema } from "./schema-to-ts.ts";
import type {
Cell,
JSONSchema,
NodeFactory,
Opaque,
OpaqueRef,
Schema,
} from "./types.ts";

export interface BuiltInLLMParams {
messages?: string[];
Expand Down
112 changes: 112 additions & 0 deletions packages/builder/src/factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/**
* Factory function to create builder functions with runtime dependency injection
*/

import type {
BuilderFunctionsAndConstants,
Cell,
CreateCellFunction,
JSONSchema,
} from "./types.ts";
import { AuthSchema, ID, ID_FIELD, NAME, schema, TYPE, UI } from "./types.ts";
import { opaqueRef, stream } from "./opaque-ref.ts";
import { getTopFrame, recipe } from "./recipe.ts";
import { byRef, compute, derive, handler, lift, render } from "./module.ts";
import {
compileAndRun,
fetchData,
ifElse,
llm,
navigateTo,
str,
streamData,
} from "./built-in.ts";
import { getCellLinkOrThrow, type Runtime } from "@commontools/runner";
import { getRecipeEnvironment } from "./env.ts";

/**
* Creates a set of builder functions with the given runtime
* @param runtime - The runtime instance to use for cell creation
* @returns An object containing all builder functions
*/
export const createBuilder = (
runtime: Runtime,
): BuilderFunctionsAndConstants => {
// Implementation of createCell moved from runner/harness
const createCell: CreateCellFunction = function createCell<T = any>(
schema?: JSONSchema,
name?: string,
value?: T,
): Cell<T> {
const frame = getTopFrame();
// This is a rather hacky way to get the context, based on the
// unsafe_binding pattern. Once we replace that mechanism, let's add nicer
// abstractions for context here as well.
const cellLink = frame?.unsafe_binding?.materialize([]);
if (!frame || !frame.cause || !cellLink) {
throw new Error(
"Can't invoke createCell outside of a lifted function or handler",
);
}
if (!getCellLinkOrThrow) {
throw new Error(
"getCellLinkOrThrow function not provided to createBuilder",
);
}
const space = getCellLinkOrThrow(cellLink).cell.space;

const cause = { parent: frame.cause } as Record<string, any>;
if (name) cause.name = name;
else cause.number = frame.generatedIdCounter++;

// Cast to Cell<T> is necessary to cast to interface-only Cell type
const cell = runtime.getCell<T>(space, cause, schema) as Cell<T>;

if (value !== undefined) cell.set(value);

return cell;
} as CreateCellFunction;

return {
// Recipe creation
recipe,

// Module creation
lift,
handler,
derive,
compute,
render,

// Built-in modules
str,
ifElse,
llm,
fetchData,
streamData,
compileAndRun,
navigateTo,

// Cell creation
createCell,
cell: opaqueRef,
stream,

// Utility
byRef,

// Environment
getRecipeEnvironment,

// Constants
ID,
ID_FIELD,
TYPE,
NAME,
UI,

// Schema utilities
schema,
AuthSchema,
};
};
49 changes: 18 additions & 31 deletions packages/builder/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
export { opaqueRef as cell, stream } from "./opaque-ref.ts";
export { $, event, select, Spell } from "./spell.ts";
export {
byRef,
compute,
createNodeFactory,
derive,
handler,
lift,
render,
} from "./module.ts";
// Export the factory function
export { createBuilder } from "./factory.ts";
export type {
BuilderFunctionsAndConstants as BuilderFunctions,
BuilderRuntime,
} from "./types.ts";

// Internal functions and exports needed by other packages
export {
getRecipeEnvironment,
type RecipeEnvironment,
Expand All @@ -19,26 +16,14 @@ export {
popFrame,
pushFrame,
pushFrameFromCause,
recipe,
recipeFromFrame,
} from "./recipe.ts";
export {
type BuiltInCompileAndRunParams,
type BuiltInCompileAndRunState,
type BuiltInLLMParams,
type BuiltInLLMState,
compileAndRun,
type createCell,
fetchData,
ifElse,
llm,
navigateTo,
str,
streamData,
} from "./built-in.ts";
export {
type Alias,
AuthSchema,
type Cell,
type Frame,
type HandlerFactory,
ID,
ID_FIELD,
isAlias,
Expand All @@ -54,16 +39,17 @@ export {
markAsStatic,
type Module,
type ModuleFactory,
type Mutable,
NAME,
type Node,
type NodeFactory,
type Opaque,
type OpaqueRef,
type OpaqueRefMethods,
type Recipe,
type RecipeFactory,
type Static,
type Schema,
schema,
type SchemaWithoutCell,
type Stream,
type StreamAlias,
type toJSON,
toOpaqueRef,
Expand All @@ -74,8 +60,9 @@ export {
unsafe_parentRecipe,
type UnsafeBinding,
} from "./types.ts";
export { type Schema, schema } from "./schema-to-ts.ts";
export { AuthSchema } from "./schema-lib.ts";
export { createNodeFactory } from "./module.ts";
export { opaqueRef as cell } from "./opaque-ref.ts";
export type { Mutable } from "@commontools/utils/types";

// This should be a separate package, but for now it's easier to keep it here.
export {
Expand Down
Loading