Skip to content

Commit

Permalink
fix!: metagen papercuts (#950)
Browse files Browse the repository at this point in the history
<!--
Pull requests are squashed and merged using:
- their title as the commit message
- their description as the commit body

Having a good title and description is important for the users to get
readable changelog.
-->

<!-- 1. Explain WHAT the change is about -->

Solves
[MET-761](https://linear.app/metatypedev/issue/MET-761/metagen-papercuts):
- Make generator naming consistent with the client_xx and fdk_xx format.
Prefer shortened names of languages like the extension name of source
files.
- Reuse a typegraph serialization across multiple generation runs in a
single cli invocation. It currently re-serializes a typegraph if it's
referenced twice.
- Explicit return types on QueryGraph methods for Typescript
- Support for non-record queries for Gql transport. Currently, one's
forced to name the query/mutation section which gets reflected in the
response name

<!-- 3. Explain HOW users should update their code -->

#### Migration notes

---

- [x] The change comes with new or modified tests
- [ ] Hard-to-understand functions have explanatory comments
- [x] End-user documentation is updated to reflect the change


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

Based on the comprehensive summary, here are the high-level release
notes:

- **Generator Naming**
  - Simplified generator names across the project
  - Updated from `fdk_typescript` → `fdk_ts`
  - Updated from `fdk_python` → `fdk_py`
  - Updated from `fdk_rust` → `fdk_rs`

- **Type Management**
- Transitioned from `Box<Typegraph>` to `Arc<Typegraph>` for improved
memory management
  - Enhanced type flexibility in query and mutation methods
  - Added support for single and multiple node operations

- **New Features**
- Added identity and identity update functions across TypeScript,
Python, and Rust clients
  - Improved caching mechanisms for typegraphs
  - Enhanced GraphQL transport layer with more flexible input handling

- **Documentation**
- Updated configuration examples and references to reflect new generator
names
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
luckasRanarison authored Feb 3, 2025
1 parent ab10235 commit f027067
Show file tree
Hide file tree
Showing 57 changed files with 1,009 additions and 360 deletions.
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ members = [
"src/common",
"src/meta-cli",
"src/metagen",
"src/metagen/src/fdk_rust/static",
"src/metagen/src/fdk_rs/static",
"src/mt_deno",
"src/typegate/engine",
"src/typegate/standalone",
Expand Down
4 changes: 2 additions & 2 deletions docs/metatype.dev/docs/guides/external-functions/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ metagen:
targets:
# named targets to configure a bunch of generators together
metagen_deno:
- generator: fdk_typescript # generator to use
- generator: fdk_ts # generator to use
# path to generate to
path: ./metagen/ts/
# point to the typegraph location
Expand Down Expand Up @@ -142,7 +142,7 @@ Within `fdk.ts` and the types and helpers, all the types from your typegraph sho

</details>

Note, this also include typescript function types for specific typegraph functions. By default, the `fdk_typescript` generator will only include stub function types for those defined on the `DenoRuntime` but this is [configurable](/docs/reference/metagen#fdk_typescript).
Note, this also include typescript function types for specific typegraph functions. By default, the `fdk_ts` generator will only include stub function types for those defined on the `DenoRuntime` but this is [configurable](/docs/reference/metagen#fdk_ts).

We can then use these types in the following manner. Add the following snippet into `metagen/ts/remix.ts`.

Expand Down
8 changes: 4 additions & 4 deletions docs/metatype.dev/docs/guides/wasm-functions/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ Note that the `WasmRuntime` constructor mentions a non-existent wasm file on dis

## Metagen

We can now tackle the boilerplate. Metagen bundles the [`fdk_rust`](/docs/reference/metagen#fdk_rust) generator which can generate all the glue code along with Rust types that correspond to our typegraph types. Let's configure a metagen target in our configuration file to get just that done.
We can now tackle the boilerplate. Metagen bundles the [`fdk_rs`](/docs/reference/metagen#fdk_rs) generator which can generate all the glue code along with Rust types that correspond to our typegraph types. Let's configure a metagen target in our configuration file to get just that done.

```yaml
metagen:
targets:
metagen_rs:
# this is the generator we're interested in
- generator: fdk_rust
- generator: fdk_rs
# the location where to put the generated files
path: ./metagen/rs/
# the path to our typegraph
Expand All @@ -69,7 +69,7 @@ This should give us the following files:
└──  fdk.rs
```

By default, the `fdk_rust` generator outputs all the necessary files required to build our wasm file. This includes the `Cargo.toml` manifest for our Rust crate.
By default, the `fdk_rs` generator outputs all the necessary files required to build our wasm file. This includes the `Cargo.toml` manifest for our Rust crate.

<CodeBlock language="toml">
{
Expand All @@ -78,7 +78,7 @@ By default, the `fdk_rust` generator outputs all the necessary files required to
}
</CodeBlock>

`fdk_rust` will not overwrite a `Cargo.toml` file discovered at generation path so you can add other dependencies if need be.
`fdk_rs` will not overwrite a `Cargo.toml` file discovered at generation path so you can add other dependencies if need be.

The `fdk.rs` file contains all the glue code including the typegraph types.

Expand Down
12 changes: 6 additions & 6 deletions docs/metatype.dev/docs/reference/metagen/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ metagen:
targets:
main:
# generator to use
- generator: fdk_rust
- generator: fdk_rs
# path to generate to
path: ./bff/
# typegraph path to use
typegraph_path: ./typegraphs/svc-bff.ts
# we can have multiple generators per target
- generator: fdk_rust
- generator: fdk_rs
path: ./telemetry/
typegraph_path: ./typegraphs/svc-telemetry.ts
# generators might have custom keys
Expand Down Expand Up @@ -118,7 +118,7 @@ This generator supports:

Refer to the [client reference](/docs/reference/typegraph/client/) for usage guidelines and examples.

### `fdk_typescript`
### `fdk_ts`

This generator supports:

Expand Down Expand Up @@ -163,14 +163,14 @@ It supports the following extra configuration keys.
| ------------------ | ---------- | ---------- | ------------------------------------------ |
| `stubbed_runtimes` | `string[]` | `["deno"]` | Runtimes for which to generate stub types. |

### `fdk_python`
### `fdk_py`

This generator supports:

- Python classes that map to typegraph types
- Decorators for custom functions implementors that require adherance to typegraph function types.
- By default, all functions from the `PythonRuntime` get stub types.
- TODO: `stubbed_runtimes` for `fdk_python`
- TODO: `stubbed_runtimes` for `fdk_py`
- TODO: types for interacting with the typegate from within custom functions.

If the referenced module for the custom function is not found, the generator will also output stub implementation (in addition to the types) at the given type. It will not replace our code on a second run.
Expand Down Expand Up @@ -202,7 +202,7 @@ Custom function:
/>
</details>

### `fdk_rust`
### `fdk_rs`

This generator generates types, serializers and bindings needed to implement custom functions in Rust. Rust implementations will need to be compiled to wasm components to be executed on the metatype platform and the generator assumes such usage.

Expand Down
6 changes: 3 additions & 3 deletions examples/metatype.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,14 @@ typegraphs:
metagen:
targets:
metagen_deno:
- generator: fdk_typescript
- generator: fdk_ts
path: ./typegraphs/metagen/ts/
typegraph_path: ./typegraphs/metagen-deno.ts
metagen_py:
- generator: fdk_python
- generator: fdk_py
path: ./typegraphs/metagen/py/
typegraph_path: ./typegraphs/metagen-py.ts
metagen_rs:
- generator: fdk_rust
- generator: fdk_rs
path: ./typegraphs/metagen/rs/
typegraph_path: ./typegraphs/metagen-rs.ts
2 changes: 1 addition & 1 deletion examples/typegraphs/metagen-sdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def metagen_sdk(g: Graph):
"targets": {
"main": [
{
"generator": "fdk_typescript",
"generator": "fdk_ts",
"typegraph_path": __file__,
"path": "funcs/",
},
Expand Down
2 changes: 1 addition & 1 deletion examples/typegraphs/metagen-sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ if (false) {
targets: {
main: [
{
generator: "fdk_typescript",
generator: "fdk_ts",
typegraph_path: myPath,
path: "funcs/",
},
Expand Down
6 changes: 3 additions & 3 deletions src/common/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use anyhow::{Context, Result};
use indoc::indoc;
use reqwest::{Client, IntoUrl, RequestBuilder, Url};
use serde::Serialize;
use std::{collections::HashMap, time::Duration};
use std::{collections::HashMap, sync::Arc, time::Duration};

use crate::{
graphql::{self, Query},
Expand Down Expand Up @@ -129,7 +129,7 @@ impl Node {
Ok(())
}

pub async fn typegraph(&self, name: &str) -> Result<Option<Box<Typegraph>>, Error> {
pub async fn typegraph(&self, name: &str) -> Result<Option<Arc<Typegraph>>, Error> {
let res = self
.post("/typegate")
.map_err(Error::Other)?
Expand Down Expand Up @@ -157,7 +157,7 @@ impl Node {
return Ok(None);
};
serde_json::from_str::<Typegraph>(&res.serialized)
.map(|tg| Some(Box::new(tg)))
.map(|tg| Some(Arc::new(tg)))
.map_err(|err| Error::Other(anyhow::anyhow!(err)))
}
}
2 changes: 1 addition & 1 deletion src/meta-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ git2 = { workspace = true, features = [
], default-features = false }

# codecs
serde.workspace = true
serde = { workspace = true, features = ["rc"] }
serde_json = { workspace = true, features = ["preserve_order"] }
flate2.workspace = true
tar.workspace = true
Expand Down
6 changes: 3 additions & 3 deletions src/meta-cli/src/cli/fdk_template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ impl Action for CreateFdkTemplate {
.context("failed to create target directory")?;

let template = match self.template {
Template::Rust => metagen::FDK_RUST_DEFAULT_TEMPLATE,
Template::Python => metagen::FDK_PYTHON_DEFAULT_TEMPLATE,
Template::Typescript => metagen::FDK_TYPESCRIPT_DEFAULT_TEMPLATE,
Template::Rust => metagen::FDK_RS_DEFAULT_TEMPLATE,
Template::Python => metagen::FDK_PY_DEFAULT_TEMPLATE,
Template::Typescript => metagen::FDK_TS_DEFAULT_TEMPLATE,
};

for (file_name, content) in template.iter() {
Expand Down
54 changes: 44 additions & 10 deletions src/meta-cli/src/cli/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::{config::Config, deploy::actors::console::ConsoleActor};
use actix::Actor;
use clap::Parser;
use common::typegraph::Typegraph;
use dashmap::DashMap;
use futures_concurrency::future::FutureGroup;
use metagen::*;

Expand Down Expand Up @@ -59,6 +60,7 @@ impl Action for Gen {
config: config.clone(),
dir,
typegate: Arc::new(node),
typegraph_cache: DashMap::new(),
};

if !mgen_conf.targets.contains_key(&self.gen_target) {
Expand Down Expand Up @@ -100,11 +102,28 @@ impl Action for Gen {
}
}

#[derive(Clone, Debug)]
#[derive(Debug)]
struct MetagenCtx {
config: Arc<Config>,
typegate: Arc<common::node::Node>,
dir: PathBuf,
typegraph_cache: DashMap<String, Arc<Typegraph>>,
}

impl MetagenCtx {
async fn get_cached_typegraph_or(
&self,
key: &str,
fetch: impl Future<Output = Result<Arc<Typegraph>>>,
) -> Result<Arc<Typegraph>> {
if let Some(cached) = self.typegraph_cache.get(key) {
Ok(cached.value().clone())
} else {
let result = fetch.await?;
self.typegraph_cache.insert(key.to_string(), result.clone());
Ok(result)
}
}
}

async fn load_fdk_template(
Expand Down Expand Up @@ -143,22 +162,37 @@ impl InputResolver for MetagenCtx {
async fn resolve(&self, order: GeneratorInputOrder) -> Result<GeneratorInputResolved> {
Ok(match order {
GeneratorInputOrder::TypegraphFromTypegate { name } => {
GeneratorInputResolved::TypegraphFromTypegate {
raw: self
.typegate
.typegraph(&name)
.await?
.with_context(|| format!("no typegraph found under {name:?}"))?,
}
let raw = self
.get_cached_typegraph_or(&name, async {
self.typegate
.typegraph(&name)
.await?
.with_context(|| format!("no typegraph found under {name:?}"))
})
.await?;

GeneratorInputResolved::TypegraphFromTypegate { raw }
}
GeneratorInputOrder::TypegraphFromPath { path, name } => {
let config = self.config.clone();
let key = format!(
"{}{}",
path.to_string_lossy(),
name.clone().unwrap_or_default()
);
let path = self
.dir
.join(path)
.canonicalize()
.wrap_err("unable to canonicalize typegraph path, make sure it exists")?;
let raw = load_tg_at(config, path, name.as_deref(), &self.dir).await?;

let raw = self
.get_cached_typegraph_or(
&key,
load_tg_at(config, path, name.as_deref(), &self.dir),
)
.await?;

GeneratorInputResolved::TypegraphFromTypegate { raw }
}
GeneratorInputOrder::LoadFdkTemplate {
Expand All @@ -178,7 +212,7 @@ async fn load_tg_at(
path: PathBuf,
name: Option<&str>,
dir: &Path,
) -> anyhow::Result<Box<Typegraph>> {
) -> anyhow::Result<Arc<Typegraph>> {
let console = ConsoleActor::new(Arc::clone(&config)).start();

let config_dir: Arc<Path> = config.dir().unwrap_or_log().into();
Expand Down
4 changes: 2 additions & 2 deletions src/meta-cli/src/cli/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,11 @@ impl Action for Serialize {

pub trait SerializeReportExt {
#[allow(clippy::vec_box)]
fn into_typegraphs(self) -> Result<Vec<Box<Typegraph>>>;
fn into_typegraphs(self) -> Result<Vec<Arc<Typegraph>>>;
}

impl SerializeReportExt for Report<SerializeAction> {
fn into_typegraphs(self) -> Result<Vec<Box<Typegraph>>> {
fn into_typegraphs(self) -> Result<Vec<Arc<Typegraph>>> {
let mut res = vec![];
for entry in self.entries.into_iter() {
match entry.status {
Expand Down
4 changes: 2 additions & 2 deletions src/meta-cli/src/deploy/actors/task/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub struct SerializeError {
pub errors: Vec<String>,
}

impl OutputData for Box<Typegraph> {
impl OutputData for Arc<Typegraph> {
fn get_typegraph_name(&self) -> String {
self.name().unwrap()
}
Expand All @@ -104,7 +104,7 @@ impl OutputData for SerializeError {
}

impl TaskAction for SerializeAction {
type SuccessData = Box<Typegraph>;
type SuccessData = Arc<Typegraph>;
type FailureData = SerializeError;
type Options = SerializeOptions;
type Generator = SerializeActionGenerator;
Expand Down
1 change: 1 addition & 0 deletions src/metagen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ serde_json.workspace = true
heck.workspace = true

# ds
dashmap.workspace = true
indexmap.workspace = true
regex.workspace = true
tera = { workspace = true, default-features = false }
Expand Down
Loading

0 comments on commit f027067

Please sign in to comment.