Skip to content

Commit

Permalink
Merge pull request #4893 from systeminit/zack/manage-other-components
Browse files Browse the repository at this point in the history
feat: create and manage other components
  • Loading branch information
zacharyhamm authored Oct 30, 2024
2 parents bce8006 + 13ed652 commit e12ce7b
Show file tree
Hide file tree
Showing 34 changed files with 1,254 additions and 188 deletions.
14 changes: 8 additions & 6 deletions bin/lang-js/src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ export interface Component {
properties: Record<string, unknown>;
}

export interface Geometry {
x: number;
y: number;
width?: number;
height?: number;
}

export interface ComponentWithGeometry {
properties: Record<string, unknown>;
geometry: {
x: string,
y: string,
width?: string,
height?: string,
}
geometry: Geometry;
}
21 changes: 15 additions & 6 deletions bin/lang-js/src/function_kinds/management.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,38 @@ import {
ResultFailure,
ResultSuccess,
} from "../function";
import { ComponentWithGeometry } from "../component";
import { ComponentWithGeometry, Geometry } from "../component";
import { RequestCtx } from "../request";

const debug = Debug("langJs:management");

export interface ManagementFunc extends Func {
thisComponent: ComponentWithGeometry
thisComponent: ComponentWithGeometry;
components: {
[key: string]: ComponentWithGeometry;
}
}

export type ManagementFuncResult =
| ManagementFuncResultSuccess
| ManagementFuncResultFailure;

export interface ManagementOperations {
create?: { [key: string]: {
kind: string;
properties?: object;
geometry?: Geometry;
} };
update?: { [key: string]: {
properties?: object;
} }
geometry?: Geometry;
} };
actions?: {
[key: string]: {
add?: string[],
remove?: string[],
}
}
};
}

export interface ManagementFuncResultSuccess extends ResultSuccess {
Expand All @@ -42,14 +51,14 @@ export interface ManagementFuncResultFailure extends ResultFailure { }
async function execute(
vm: NodeVM,
{ executionId }: RequestCtx,
{ thisComponent }: ManagementFunc,
{ thisComponent, components }: ManagementFunc,
code: string,
): Promise<ManagementFuncResult> {
let managementResult: Record<string, unknown> | undefined | null;
try {
const runner = vm.run(code);
managementResult = await new Promise((resolve) => {
runner({ thisComponent }, (resolution: Record<string, unknown>) => resolve(resolution));
runner({ thisComponent, components }, (resolution: Record<string, unknown>) => resolve(resolution));
});
} catch (err) {
return failureExecution(err as Error, executionId);
Expand Down
6 changes: 5 additions & 1 deletion lib/cyclone-client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ impl Default for ClientConfig {
#[allow(clippy::panic, clippy::assertions_on_constants)]
#[cfg(test)]
mod tests {
use std::{env, path::Path};
use std::{collections::HashMap, env, path::Path};

use base64::{engine::general_purpose, Engine};
use buck2_resources::Buck2Resources;
Expand Down Expand Up @@ -1326,9 +1326,11 @@ mod tests {
execution_id: "1234".to_string(),
handler: "manage".to_string(),
this_component: ComponentViewWithGeometry {
kind: None,
properties: serde_json::json!({"it": "is", "a": "principle", "of": "music", "to": "repeat the theme"}),
geometry: serde_json::json!({"x": "1", "y": "2"}),
},
components: HashMap::new(),
code_base64: base64_encode(
r#"function manage(input) {
console.log('first');
Expand Down Expand Up @@ -1408,9 +1410,11 @@ mod tests {
execution_id: "1234".to_string(),
handler: "manage".to_string(),
this_component: ComponentViewWithGeometry {
kind: None,
properties: serde_json::json!({"it": "is", "a": "principle", "of": "music", "to": "repeat the theme"}),
geometry: serde_json::json!({"x": "1", "y": "2"}),
},
components: HashMap::new(),
code_base64: base64_encode(
r#"function manage({ thisComponent }) {
console.log('first');
Expand Down
3 changes: 3 additions & 0 deletions lib/cyclone-core/src/component_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,16 @@ impl Default for ComponentView {
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ComponentViewWithGeometry {
// This is not component kind. Instead it's a schema name
pub kind: Option<String>,
pub properties: Value,
pub geometry: Value,
}

impl Default for ComponentViewWithGeometry {
fn default() -> Self {
Self {
kind: None,
properties: serde_json::json!({}),
geometry: serde_json::json!({}),
}
Expand Down
3 changes: 3 additions & 0 deletions lib/cyclone-core/src/management.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashMap;

use serde::{Deserialize, Serialize};
use telemetry::prelude::*;
use telemetry_utils::metric;
Expand All @@ -11,6 +13,7 @@ pub struct ManagementRequest {
pub handler: String,
pub code_base64: String,
pub this_component: ComponentViewWithGeometry,
pub components: HashMap<String, ComponentViewWithGeometry>,
pub before: Vec<BeforeFunction>,
}

Expand Down
2 changes: 1 addition & 1 deletion lib/dal-test/src/expected.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ impl ExpectComponent {
.geometry(ctx)
.await
.expect("get geometry for component")
.raw()
.into_raw()
}

pub async fn view(self, ctx: &DalContext) -> Option<serde_json::Value> {
Expand Down
90 changes: 89 additions & 1 deletion lib/dal-test/src/test_exclusive_schemas/legos/small.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashSet;

use dal::action::prototype::ActionKind;
use dal::pkg::{import_pkg_from_pkg, ImportOptions};
use dal::{BuiltinsResult, DalContext};
Expand All @@ -11,6 +13,7 @@ use crate::test_exclusive_schemas::legos::bricks::LegoBricks;
use crate::test_exclusive_schemas::{
build_action_func, build_asset_func, build_management_func,
build_resource_payload_to_value_func, create_identity_func, PKG_CREATED_BY, PKG_VERSION,
SCHEMA_ID_SMALL_EVEN_LEGO,
};

pub(crate) async fn migrate_test_exclusive_schema_small_odd_lego(
Expand Down Expand Up @@ -59,7 +62,7 @@ pub(crate) async fn migrate_test_exclusive_schema_small_odd_lego(
let import_management_func_code =
"async function main({ thisComponent }: Input): Promise<Output> {
const thisProperties = thisComponent.properties;
return {
return {
status: 'ok',
ops: {
update: {
Expand All @@ -81,6 +84,71 @@ pub(crate) async fn migrate_test_exclusive_schema_small_odd_lego(
let import_management_func =
build_management_func(import_management_func_code, import_management_func_name)?;

let simple_create_mgmt_func_code = r#"
async function main({ thisComponent, components }: Input): Promise<Output> {
const thisName = thisComponent.properties?.si?.name ?? "unknown";
let create = {
[`${thisName}_clone`]: {
properties: {
...thisComponent.properties,
},
geometry: {
x: 10,
y: 20,
}
}
};
for (let [id, component] of Object.entries(components)) {
const name = component.properties?.si?.name ?? "unknown";
let clone_name = `${name}_clone`;
if (clone_name in create) {
clone_name = `${clone_name}-${id}`;
}
create[clone_name] = {
...component,
};
}
return {
status: "ok",
ops: { create };
}
}
"#;

let clone_me_mgmt_func_name = "test:cloneMeSmallLego";
let clone_me_mgmt_func =
build_management_func(simple_create_mgmt_func_code, clone_me_mgmt_func_name)?;

let update_managed_func_code = r#"
async function main({ thisComponent, components }: Input): Promise<Output> {
const thisName = thisComponent.properties?.si?.name ?? "unknown";
const update: { [key: string]: unknown } = {};
for (let [id, component] of Object.entries(components)) {
let name = component.properties?.si?.name ?? "unknown";
update[id] = {
properties: {
...component.properties,
si: {
...component.properties?.si,
name: `${name} managed by ${thisName}`,
}
},
};
}
return {
status: "ok",
ops: { update };
}
}
"#;
let update_mgmt_func_name = "test:updateManagedComponent";
let update_mgmt_func = build_management_func(update_managed_func_code, update_mgmt_func_name)?;

let fn_name = "test:deleteActionSmallLego";
let delete_action_func = build_action_func(delete_action_code, fn_name)?;

Expand Down Expand Up @@ -149,6 +217,24 @@ pub(crate) async fn migrate_test_exclusive_schema_small_odd_lego(
.func_unique_id(&import_management_func.unique_id)
.build()?,
)
.management_func(
ManagementFuncSpec::builder()
.name("Clone")
.managed_schemas(Some(HashSet::from([
SCHEMA_ID_SMALL_EVEN_LEGO.to_string()
])))
.func_unique_id(&clone_me_mgmt_func.unique_id)
.build()?,
)
.management_func(
ManagementFuncSpec::builder()
.name("Update")
.managed_schemas(Some(HashSet::from([
SCHEMA_ID_SMALL_EVEN_LEGO.to_string()
])))
.func_unique_id(&update_mgmt_func.unique_id)
.build()?,
)
.build()?,
)
.build()?;
Expand All @@ -162,6 +248,8 @@ pub(crate) async fn migrate_test_exclusive_schema_small_odd_lego(
.func(small_lego_authoring_schema_func)
.func(resource_payload_to_value_func)
.func(import_management_func)
.func(clone_me_mgmt_func)
.func(update_mgmt_func)
.schema(small_lego_schema)
.build()?;

Expand Down
Loading

0 comments on commit e12ce7b

Please sign in to comment.