From 246d57a9a581305508aba09c0d6a055c5b98efc1 Mon Sep 17 00:00:00 2001 From: alex leon Date: Thu, 9 Apr 2026 17:09:54 +0200 Subject: [PATCH 01/17] Add new field to petrinaut arcs type: inhibitor | standard --- .../petrinaut/src/clipboard/paste.test.ts | 24 ++++++--- .../petrinaut/src/clipboard/serialize.test.ts | 6 +-- .../petrinaut/src/clipboard/types.ts | 1 + .../petrinaut/src/core/types/sdcpn.ts | 10 +++- .../petrinaut/src/examples/broken-machines.ts | 19 +++++++ .../src/examples/satellites-launcher.ts | 5 ++ .../petrinaut/src/examples/satellites.ts | 4 ++ .../petrinaut/src/examples/sir-model.ts | 5 ++ .../src/examples/supply-chain-stochastic.ts | 22 ++++---- .../petrinaut/src/examples/supply-chain.ts | 20 +++---- .../petrinaut/src/file-format/types.ts | 1 + .../petrinaut/src/lib/deep-equal.test.ts | 4 +- .../petrinaut/src/lsp/lib/checker.test.ts | 54 +++++++++---------- .../lib/create-sdcpn-language-service.test.ts | 16 ++++-- .../simulator/build-simulation.test.ts | 8 +-- .../check-transition-enablement.test.ts | 26 ++++----- .../simulator/compute-next-frame.test.ts | 4 +- .../compute-possible-transition.test.ts | 6 +-- .../simulator/execute-transitions.test.ts | 28 +++++----- .../src/state/mutation-provider.test.tsx | 8 +-- .../petrinaut/src/state/mutation-provider.tsx | 1 + .../properties-panel.stories.tsx | 6 +-- .../SDCPN/hooks/use-sdcpn-to-react-flow.ts | 2 + 23 files changed, 171 insertions(+), 109 deletions(-) diff --git a/libs/@hashintel/petrinaut/src/clipboard/paste.test.ts b/libs/@hashintel/petrinaut/src/clipboard/paste.test.ts index 7a7e123c759..fdb892caa51 100644 --- a/libs/@hashintel/petrinaut/src/clipboard/paste.test.ts +++ b/libs/@hashintel/petrinaut/src/clipboard/paste.test.ts @@ -420,8 +420,12 @@ describe("paste — arc remapping", () => { { id: "transition__old-t1", name: "T1", - inputArcs: [{ placeId: "place__old-p1", weight: 3 }], - outputArcs: [{ placeId: "place__old-p1", weight: 1 }], + inputArcs: [ + { placeId: "place__old-p1", weight: 3, type: "standard" }, + ], + outputArcs: [ + { placeId: "place__old-p1", weight: 1, type: "standard" }, + ], lambdaType: "predicate", lambdaCode: "", transitionKernelCode: "", @@ -449,8 +453,12 @@ describe("paste — arc remapping", () => { { id: "transition__old", name: "T1", - inputArcs: [{ placeId: "place__missing", weight: 1 }], - outputArcs: [{ placeId: "place__missing", weight: 1 }], + inputArcs: [ + { placeId: "place__missing", weight: 1, type: "standard" }, + ], + outputArcs: [ + { placeId: "place__missing", weight: 1, type: "standard" }, + ], lambdaType: "predicate", lambdaCode: "", transitionKernelCode: "", @@ -485,10 +493,12 @@ describe("paste — arc remapping", () => { id: "transition__t1", name: "T1", inputArcs: [ - { placeId: "place__included", weight: 1 }, - { placeId: "place__excluded", weight: 2 }, + { placeId: "place__included", weight: 1, type: "standard" }, + { placeId: "place__excluded", weight: 2, type: "standard" }, + ], + outputArcs: [ + { placeId: "place__excluded", weight: 1, type: "standard" }, ], - outputArcs: [{ placeId: "place__excluded", weight: 1 }], lambdaType: "predicate", lambdaCode: "", transitionKernelCode: "", diff --git a/libs/@hashintel/petrinaut/src/clipboard/serialize.test.ts b/libs/@hashintel/petrinaut/src/clipboard/serialize.test.ts index 8bdfff0a7fd..077bdaa9260 100644 --- a/libs/@hashintel/petrinaut/src/clipboard/serialize.test.ts +++ b/libs/@hashintel/petrinaut/src/clipboard/serialize.test.ts @@ -46,8 +46,8 @@ const fullNet: SDCPN = { { id: "t1", name: "Transition1", - inputArcs: [{ placeId: "p1", weight: 1 }], - outputArcs: [{ placeId: "p2", weight: 2 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "p2", weight: 2, type: "standard" }], lambdaType: "predicate", lambdaCode: "return true;", transitionKernelCode: "return input;", @@ -466,7 +466,7 @@ describe("parseClipboardPayload", () => { { id: "t1", name: "T", - inputArcs: [{ placeId: "p1", weight: "heavy" }], + inputArcs: [{ placeId: "p1", weight: "heavy", type: "standard" }], outputArcs: [], lambdaType: "predicate", lambdaCode: "", diff --git a/libs/@hashintel/petrinaut/src/clipboard/types.ts b/libs/@hashintel/petrinaut/src/clipboard/types.ts index 20dcde00d8f..1a0351877c0 100644 --- a/libs/@hashintel/petrinaut/src/clipboard/types.ts +++ b/libs/@hashintel/petrinaut/src/clipboard/types.ts @@ -5,6 +5,7 @@ export const CLIPBOARD_FORMAT_VERSION = 1; const arcSchema = z.object({ placeId: z.string(), weight: z.number(), + type: z.enum(["standard", "inhibitor"]).optional().default("standard"), }); const placeSchema = z.object({ diff --git a/libs/@hashintel/petrinaut/src/core/types/sdcpn.ts b/libs/@hashintel/petrinaut/src/core/types/sdcpn.ts index 383ecf94bd9..7356b0a305b 100644 --- a/libs/@hashintel/petrinaut/src/core/types/sdcpn.ts +++ b/libs/@hashintel/petrinaut/src/core/types/sdcpn.ts @@ -1,10 +1,16 @@ export type ID = string; +export type Arc = { + placeId: string; + weight: number; + type: "standard" | "inhibitor"; +}; + export type Transition = { id: ID; name: string; - inputArcs: { placeId: string; weight: number }[]; - outputArcs: { placeId: string; weight: number }[]; + inputArcs: Arc[]; + outputArcs: Arc[]; lambdaType: "predicate" | "stochastic"; lambdaCode: string; transitionKernelCode: string; diff --git a/libs/@hashintel/petrinaut/src/examples/broken-machines.ts b/libs/@hashintel/petrinaut/src/examples/broken-machines.ts index 76ec640af3c..c18f6bfdebb 100644 --- a/libs/@hashintel/petrinaut/src/examples/broken-machines.ts +++ b/libs/@hashintel/petrinaut/src/examples/broken-machines.ts @@ -105,16 +105,19 @@ export const productionMachines: { title: string; petriNetDefinition: SDCPN } = { placeId: "place__81e551b4-11dc-4781-9cd7-dd882fd7e947", weight: 1, + type: "standard", }, ], outputArcs: [ { placeId: "place__7b695ff5-a397-4237-8e30-ddf8cbc9e2c4", weight: 1, + type: "standard", }, { placeId: "place__2bdd959f-a5bc-404a-bd03-34fafcef66b8", weight: 1, + type: "standard", }, ], lambdaType: "predicate", @@ -132,16 +135,19 @@ export const productionMachines: { title: string; petriNetDefinition: SDCPN } = { placeId: "place__81e551b4-11dc-4781-9cd7-dd882fd7e947", weight: 1, + type: "standard", }, ], outputArcs: [ { placeId: "place__d5f92ae2-c8c4-49cb-935e-4a35e4f7b5fe", weight: 1, + type: "standard", }, { placeId: "place__e5af0410-d80a-4c8b-b3bf-692918b98e6c", weight: 1, + type: "standard", }, ], lambdaType: "stochastic", @@ -159,16 +165,19 @@ export const productionMachines: { title: string; petriNetDefinition: SDCPN } = { placeId: "place__d662407f-c56d-4a96-bcbb-ead785a9c594", weight: 1, + type: "standard", }, { placeId: "place__2bdd959f-a5bc-404a-bd03-34fafcef66b8", weight: 1, + type: "standard", }, ], outputArcs: [ { placeId: "place__81e551b4-11dc-4781-9cd7-dd882fd7e947", weight: 1, + type: "standard", }, ], lambdaType: "predicate", @@ -185,12 +194,14 @@ export const productionMachines: { title: string; petriNetDefinition: SDCPN } = { placeId: "place__17c65d6e-0c3e-48e6-a677-2914e28131ac", weight: 1, + type: "standard", }, ], outputArcs: [ { placeId: "place__2bdd959f-a5bc-404a-bd03-34fafcef66b8", weight: 1, + type: "standard", }, ], lambdaType: "predicate", @@ -208,16 +219,19 @@ export const productionMachines: { title: string; petriNetDefinition: SDCPN } = { placeId: "place__e5af0410-d80a-4c8b-b3bf-692918b98e6c", weight: 1, + type: "standard", }, ], outputArcs: [ { placeId: "place__4b72cf19-907b-4fc0-ac0a-555453e95d4b", weight: 1, + type: "standard", }, { placeId: "place__9cb073fb-f1d7-4613-8b10-8d1b08796f24", weight: 1, + type: "standard", }, ], lambdaType: "predicate", @@ -234,12 +248,14 @@ export const productionMachines: { title: string; petriNetDefinition: SDCPN } = { placeId: "place__4b72cf19-907b-4fc0-ac0a-555453e95d4b", weight: 1, + type: "standard", }, ], outputArcs: [ { placeId: "place__eaca89b8-1db1-45fa-8c3a-6eb6f0419ffa", weight: 1, + type: "standard", }, ], lambdaType: "predicate", @@ -257,16 +273,19 @@ export const productionMachines: { title: string; petriNetDefinition: SDCPN } = { placeId: "place__eaca89b8-1db1-45fa-8c3a-6eb6f0419ffa", weight: 1, + type: "standard", }, { placeId: "place__9cb073fb-f1d7-4613-8b10-8d1b08796f24", weight: 1, + type: "standard", }, ], outputArcs: [ { placeId: "place__17c65d6e-0c3e-48e6-a677-2914e28131ac", weight: 1, + type: "standard", }, ], lambdaType: "predicate", diff --git a/libs/@hashintel/petrinaut/src/examples/satellites-launcher.ts b/libs/@hashintel/petrinaut/src/examples/satellites-launcher.ts index ccbbf01bdc3..c6023d77bb5 100644 --- a/libs/@hashintel/petrinaut/src/examples/satellites-launcher.ts +++ b/libs/@hashintel/petrinaut/src/examples/satellites-launcher.ts @@ -119,12 +119,14 @@ export const probabilisticSatellitesSDCPN: { { placeId: "3cbc7944-34cb-4eeb-b779-4e392a171fe1", weight: 2, + type: "standard", }, ], outputArcs: [ { placeId: "ea42ba61-03ea-4940-b2e2-b594d5331a71", weight: 2, + type: "standard", }, ], lambdaType: "predicate", @@ -172,12 +174,14 @@ export default TransitionKernel((tokens) => { { placeId: "3cbc7944-34cb-4eeb-b779-4e392a171fe1", weight: 1, + type: "standard", }, ], outputArcs: [ { placeId: "ea42ba61-03ea-4940-b2e2-b594d5331a71", weight: 1, + type: "standard", }, ], lambdaType: "predicate", @@ -219,6 +223,7 @@ export default TransitionKernel((tokens) => { { placeId: "3cbc7944-34cb-4eeb-b779-4e392a171fe1", weight: 1, + type: "standard", }, ], lambdaType: "stochastic", diff --git a/libs/@hashintel/petrinaut/src/examples/satellites.ts b/libs/@hashintel/petrinaut/src/examples/satellites.ts index 92e9114ceb0..d7bc0e162ec 100644 --- a/libs/@hashintel/petrinaut/src/examples/satellites.ts +++ b/libs/@hashintel/petrinaut/src/examples/satellites.ts @@ -116,12 +116,14 @@ export const satellitesSDCPN: { title: string; petriNetDefinition: SDCPN } = { { placeId: "3cbc7944-34cb-4eeb-b779-4e392a171fe1", weight: 2, + type: "standard", }, ], outputArcs: [ { placeId: "ea42ba61-03ea-4940-b2e2-b594d5331a71", weight: 2, + type: "standard", }, ], lambdaType: "predicate", @@ -169,12 +171,14 @@ export default TransitionKernel((tokens) => { { placeId: "3cbc7944-34cb-4eeb-b779-4e392a171fe1", weight: 1, + type: "standard", }, ], outputArcs: [ { placeId: "ea42ba61-03ea-4940-b2e2-b594d5331a71", weight: 1, + type: "standard", }, ], lambdaType: "predicate", diff --git a/libs/@hashintel/petrinaut/src/examples/sir-model.ts b/libs/@hashintel/petrinaut/src/examples/sir-model.ts index 240f7a1760a..80e5ad1f5ca 100644 --- a/libs/@hashintel/petrinaut/src/examples/sir-model.ts +++ b/libs/@hashintel/petrinaut/src/examples/sir-model.ts @@ -41,16 +41,19 @@ export const sirModel: { title: string; petriNetDefinition: SDCPN } = { { placeId: "place__susceptible", weight: 1, + type: "standard", }, { placeId: "place__infected", weight: 1, + type: "standard", }, ], outputArcs: [ { placeId: "place__infected", weight: 2, + type: "standard", }, ], lambdaType: "stochastic", @@ -68,12 +71,14 @@ export const sirModel: { title: string; petriNetDefinition: SDCPN } = { { placeId: "place__infected", weight: 1, + type: "standard", }, ], outputArcs: [ { placeId: "place__recovered", weight: 1, + type: "standard", }, ], lambdaType: "stochastic", diff --git a/libs/@hashintel/petrinaut/src/examples/supply-chain-stochastic.ts b/libs/@hashintel/petrinaut/src/examples/supply-chain-stochastic.ts index 3c25a8c8940..dfa174992d1 100644 --- a/libs/@hashintel/petrinaut/src/examples/supply-chain-stochastic.ts +++ b/libs/@hashintel/petrinaut/src/examples/supply-chain-stochastic.ts @@ -77,10 +77,10 @@ export const supplyChainStochasticSDCPN: { id: "transition__0", name: "Deliver to Plant", inputArcs: [ - { placeId: "place__0", weight: 1 }, - { placeId: "place__1", weight: 1 }, + { placeId: "place__0", weight: 1, type: "standard" }, + { placeId: "place__1", weight: 1, type: "standard" }, ], - outputArcs: [{ placeId: "place__2", weight: 1 }], + outputArcs: [{ placeId: "place__2", weight: 1, type: "standard" }], lambdaType: "stochastic", lambdaCode: "export default Lambda(() => 1);", transitionKernelCode: "", @@ -90,8 +90,8 @@ export const supplyChainStochasticSDCPN: { { id: "transition__1", name: "Manufacture", - inputArcs: [{ placeId: "place__2", weight: 1 }], - outputArcs: [{ placeId: "place__3", weight: 1 }], + inputArcs: [{ placeId: "place__2", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "place__3", weight: 1, type: "standard" }], lambdaType: "stochastic", lambdaCode: "export default Lambda(() => 1);", transitionKernelCode: `// Produce a product with random quality @@ -108,8 +108,8 @@ export default TransitionKernel(() => { { id: "transition__2", name: "Dispatch", - inputArcs: [{ placeId: "place__3", weight: 1 }], - outputArcs: [{ placeId: "place__5", weight: 1 }], + inputArcs: [{ placeId: "place__3", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "place__5", weight: 1, type: "standard" }], lambdaType: "predicate", lambdaCode: `// Dispatch if product quality exceeds the quality threshold export default Lambda((tokens, parameters) => { @@ -123,8 +123,8 @@ export default Lambda((tokens, parameters) => { { id: "transition__3", name: "Dispose", - inputArcs: [{ placeId: "place__3", weight: 1 }], - outputArcs: [{ placeId: "place__4", weight: 1 }], + inputArcs: [{ placeId: "place__3", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "place__4", weight: 1, type: "standard" }], lambdaType: "predicate", lambdaCode: `// Dispose if product quality is below the quality threshold export default Lambda((tokens, parameters) => { @@ -138,8 +138,8 @@ export default Lambda((tokens, parameters) => { { id: "transition__4", name: "Ship", - inputArcs: [{ placeId: "place__5", weight: 1 }], - outputArcs: [{ placeId: "place__6", weight: 1 }], + inputArcs: [{ placeId: "place__5", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "place__6", weight: 1, type: "standard" }], lambdaType: "stochastic", lambdaCode: "export default Lambda(() => 1 / 3);", transitionKernelCode: "", diff --git a/libs/@hashintel/petrinaut/src/examples/supply-chain.ts b/libs/@hashintel/petrinaut/src/examples/supply-chain.ts index f756ec3dcdc..564da9ff2bd 100644 --- a/libs/@hashintel/petrinaut/src/examples/supply-chain.ts +++ b/libs/@hashintel/petrinaut/src/examples/supply-chain.ts @@ -74,10 +74,10 @@ export const supplyChainSDCPN: { title: string; petriNetDefinition: SDCPN } = { id: "transition__0", name: "Deliver to Plant", inputArcs: [ - { placeId: "place__0", weight: 1 }, - { placeId: "place__1", weight: 1 }, + { placeId: "place__0", weight: 1, type: "standard" }, + { placeId: "place__1", weight: 1, type: "standard" }, ], - outputArcs: [{ placeId: "place__2", weight: 1 }], + outputArcs: [{ placeId: "place__2", weight: 1, type: "standard" }], lambdaType: "predicate", lambdaCode: "export default Lambda(() => true);", transitionKernelCode: "", @@ -87,8 +87,8 @@ export const supplyChainSDCPN: { title: string; petriNetDefinition: SDCPN } = { { id: "transition__1", name: "Manufacture", - inputArcs: [{ placeId: "place__2", weight: 1 }], - outputArcs: [{ placeId: "place__3", weight: 1 }], + inputArcs: [{ placeId: "place__2", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "place__3", weight: 1, type: "standard" }], lambdaType: "predicate", lambdaCode: "export default Lambda(() => true);", transitionKernelCode: "", @@ -98,10 +98,10 @@ export const supplyChainSDCPN: { title: string; petriNetDefinition: SDCPN } = { { id: "transition__2", name: "Quality Check", - inputArcs: [{ placeId: "place__3", weight: 1 }], + inputArcs: [{ placeId: "place__3", weight: 1, type: "standard" }], outputArcs: [ - { placeId: "place__5", weight: 1 }, - { placeId: "place__4", weight: 1 }, + { placeId: "place__5", weight: 1, type: "standard" }, + { placeId: "place__4", weight: 1, type: "standard" }, ], lambdaType: "predicate", lambdaCode: "export default Lambda(() => true);", @@ -112,8 +112,8 @@ export const supplyChainSDCPN: { title: string; petriNetDefinition: SDCPN } = { { id: "transition__3", name: "Ship", - inputArcs: [{ placeId: "place__5", weight: 1 }], - outputArcs: [{ placeId: "place__6", weight: 1 }], + inputArcs: [{ placeId: "place__5", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "place__6", weight: 1, type: "standard" }], lambdaType: "predicate", lambdaCode: "export default Lambda(() => true);", transitionKernelCode: "", diff --git a/libs/@hashintel/petrinaut/src/file-format/types.ts b/libs/@hashintel/petrinaut/src/file-format/types.ts index a18229bd9f7..57226078d38 100644 --- a/libs/@hashintel/petrinaut/src/file-format/types.ts +++ b/libs/@hashintel/petrinaut/src/file-format/types.ts @@ -5,6 +5,7 @@ export const SDCPN_FILE_FORMAT_VERSION = 1; const arcSchema = z.object({ placeId: z.string(), weight: z.number(), + type: z.enum(["standard", "inhibitor"]).optional().default("standard"), }); const placeSchema = z.object({ diff --git a/libs/@hashintel/petrinaut/src/lib/deep-equal.test.ts b/libs/@hashintel/petrinaut/src/lib/deep-equal.test.ts index 2947827008d..b967db9d355 100644 --- a/libs/@hashintel/petrinaut/src/lib/deep-equal.test.ts +++ b/libs/@hashintel/petrinaut/src/lib/deep-equal.test.ts @@ -27,8 +27,8 @@ const sampleNet: SDCPN = { { id: "t1", name: "Transition 1", - inputArcs: [{ placeId: "p1", weight: 1 }], - outputArcs: [{ placeId: "p1", weight: 2 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "p1", weight: 2, type: "standard" }], lambdaType: "predicate", lambdaCode: "return true;", transitionKernelCode: "return input;", diff --git a/libs/@hashintel/petrinaut/src/lsp/lib/checker.test.ts b/libs/@hashintel/petrinaut/src/lsp/lib/checker.test.ts index 4fdb53700e5..25d1b86ecb1 100644 --- a/libs/@hashintel/petrinaut/src/lsp/lib/checker.test.ts +++ b/libs/@hashintel/petrinaut/src/lsp/lib/checker.test.ts @@ -39,8 +39,8 @@ describe("checkSDCPN", () => { { id: "t1", lambdaType: "predicate", - inputArcs: [{ placeId: "place1", weight: 1 }], - outputArcs: [{ placeId: "place2", weight: 1 }], + inputArcs: [{ placeId: "place1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "place2", weight: 1, type: "standard" }], lambdaCode: `export default Lambda((input, parameters) => { return input.Source[0].value > 0; });`, @@ -223,7 +223,7 @@ describe("checkSDCPN", () => { { id: "t1", lambdaType: "predicate", - inputArcs: [{ placeId: "place1", weight: 1 }], + inputArcs: [{ placeId: "place1", weight: 1, type: "standard" }], outputArcs: [], lambdaCode: `export default Lambda((input, parameters) => { const token = input.Source[0]; @@ -250,7 +250,7 @@ describe("checkSDCPN", () => { { id: "t1", lambdaType: "predicate", - inputArcs: [{ placeId: "place1", weight: 1 }], + inputArcs: [{ placeId: "place1", weight: 1, type: "standard" }], outputArcs: [], lambdaCode: `export default Lambda((input, parameters) => { const token = input.UndefinedPlace[0]; @@ -283,7 +283,7 @@ describe("checkSDCPN", () => { { id: "t1", lambdaType: "predicate", - inputArcs: [{ placeId: "place1", weight: 1 }], + inputArcs: [{ placeId: "place1", weight: 1, type: "standard" }], outputArcs: [], lambdaCode: `export default Lambda((input, parameters) => { return 42; @@ -312,7 +312,7 @@ describe("checkSDCPN", () => { { id: "t1", lambdaType: "stochastic", - inputArcs: [{ placeId: "place1", weight: 1 }], + inputArcs: [{ placeId: "place1", weight: 1, type: "standard" }], outputArcs: [], lambdaCode: `export default Lambda((input, parameters) => { return input.Source[0].rate; @@ -342,8 +342,8 @@ describe("checkSDCPN", () => { transitions: [ { id: "t1", - inputArcs: [{ placeId: "place1", weight: 1 }], - outputArcs: [{ placeId: "place2", weight: 1 }], + inputArcs: [{ placeId: "place1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "place2", weight: 1, type: "standard" }], transitionKernelCode: `export default TransitionKernel((input, parameters) => { return { Target: [input.Source[0]] }; });`, @@ -370,8 +370,8 @@ describe("checkSDCPN", () => { transitions: [ { id: "t1", - inputArcs: [{ placeId: "place1", weight: 1 }], - outputArcs: [{ placeId: "place2", weight: 1 }], + inputArcs: [{ placeId: "place1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "place2", weight: 1, type: "standard" }], transitionKernelCode: `export default TransitionKernel((input, parameters) => { return { WrongPlace: [input.Source[0]] }; });`, @@ -401,8 +401,8 @@ describe("checkSDCPN", () => { transitions: [ { id: "t1", - inputArcs: [{ placeId: "place1", weight: 1 }], - outputArcs: [{ placeId: "place2", weight: 2 }], // expects 2 tokens + inputArcs: [{ placeId: "place1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "place2", weight: 2, type: "standard" }], // expects 2 tokens transitionKernelCode: `export default TransitionKernel((input, parameters) => { return { Target: [input.Source[0]] }; });`, @@ -435,8 +435,8 @@ describe("checkSDCPN", () => { transitions: [ { id: "t1", - inputArcs: [{ placeId: "place1", weight: 1 }], - outputArcs: [{ placeId: "place2", weight: 1 }], + inputArcs: [{ placeId: "place1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "place2", weight: 1, type: "standard" }], transitionKernelCode: `export default TransitionKernel((input, parameters) => { const newX = input.Source[0].x * parameters.multiplier; return { Target: [{ x: newX }] }; @@ -466,10 +466,10 @@ describe("checkSDCPN", () => { { id: "t1", inputArcs: [ - { placeId: "place1", weight: 1 }, - { placeId: "place2", weight: 1 }, + { placeId: "place1", weight: 1, type: "standard" }, + { placeId: "place2", weight: 1, type: "standard" }, ], - outputArcs: [{ placeId: "place3", weight: 1 }], + outputArcs: [{ placeId: "place3", weight: 1, type: "standard" }], transitionKernelCode: `export default TransitionKernel((input, parameters) => { // Accessing Untyped should fail since it has no color const token = input.Untyped[0]; @@ -505,10 +505,10 @@ describe("checkSDCPN", () => { transitions: [ { id: "t1", - inputArcs: [{ placeId: "place1", weight: 1 }], + inputArcs: [{ placeId: "place1", weight: 1, type: "standard" }], outputArcs: [ - { placeId: "place2", weight: 1 }, - { placeId: "place3", weight: 1 }, + { placeId: "place2", weight: 1, type: "standard" }, + { placeId: "place3", weight: 1, type: "standard" }, ], transitionKernelCode: `export default TransitionKernel((input, parameters) => { // Missing Target which is required - should fail @@ -540,8 +540,8 @@ describe("checkSDCPN", () => { transitions: [ { id: "t1", - inputArcs: [{ placeId: "place1", weight: 1 }], - outputArcs: [{ placeId: "place2", weight: 1 }], + inputArcs: [{ placeId: "place1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "place2", weight: 1, type: "standard" }], transitionKernelCode: `export default TransitionKernel((input, parameters) => { // Accessing 'nonExistentProperty' should fail since color1 only has 'x' const value = input.Source[0].nonExistentProperty; @@ -585,7 +585,7 @@ describe("checkSDCPN", () => { { id: "t1", lambdaType: "predicate", - inputArcs: [{ placeId: "place1", weight: 1 }], + inputArcs: [{ placeId: "place1", weight: 1, type: "standard" }], outputArcs: [], lambdaCode: `export default Lambda((input, parameters) => { return input.UndefinedPlace[0]; @@ -625,7 +625,7 @@ describe("checkSDCPN", () => { { id: "transitionA", lambdaType: "predicate", - inputArcs: [{ placeId: "placeIn", weight: 1 }], + inputArcs: [{ placeId: "placeIn", weight: 1, type: "standard" }], outputArcs: [], lambdaCode: `export default Lambda((input, parameters) => { return input.PlaceIn[0].x > 0; @@ -638,7 +638,7 @@ describe("checkSDCPN", () => { { id: "transitionB", lambdaType: "predicate", - inputArcs: [{ placeId: "placeIn", weight: 1 }], + inputArcs: [{ placeId: "placeIn", weight: 1, type: "standard" }], outputArcs: [], lambdaCode: `export default Lambda((input, parameters) => { return input.PlaceIn[0].x < 100; @@ -673,8 +673,8 @@ describe("checkSDCPN", () => { { id: "transitionA", lambdaType: "predicate", - inputArcs: [{ placeId: "placeIn", weight: 1 }], - outputArcs: [{ placeId: "placeOut", weight: 1 }], + inputArcs: [{ placeId: "placeIn", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "placeOut", weight: 1, type: "standard" }], lambdaCode: `export default Lambda((input, parameters) => { return input.PlaceIn[0].x > 0; });`, diff --git a/libs/@hashintel/petrinaut/src/lsp/lib/create-sdcpn-language-service.test.ts b/libs/@hashintel/petrinaut/src/lsp/lib/create-sdcpn-language-service.test.ts index 68d0a6e7ccf..ac67638d670 100644 --- a/libs/@hashintel/petrinaut/src/lsp/lib/create-sdcpn-language-service.test.ts +++ b/libs/@hashintel/petrinaut/src/lsp/lib/create-sdcpn-language-service.test.ts @@ -110,8 +110,12 @@ describe("SDCPNLanguageServer completions", () => { { id: "t1", lambdaType: "predicate" as const, - inputArcs: [{ placeId: "place1", weight: 1 }], - outputArcs: [{ placeId: "place2", weight: 1 }], + inputArcs: [ + { placeId: "place1", weight: 1, type: "standard" as const }, + ], + outputArcs: [ + { placeId: "place2", weight: 1, type: "standard" as const }, + ], lambdaCode: "", transitionKernelCode: "", }, @@ -290,7 +294,9 @@ describe("SDCPNLanguageServer completions", () => { { id: "t1", lambdaType: "predicate" as const, - inputArcs: [{ placeId: "place1", weight: 1 }], + inputArcs: [ + { placeId: "place1", weight: 1, type: "standard" as const }, + ], outputArcs: [], lambdaCode: "", }, @@ -314,7 +320,9 @@ describe("SDCPNLanguageServer completions", () => { { id: "t1", lambdaType: "predicate" as const, - inputArcs: [{ placeId: "place1", weight: 1 }], + inputArcs: [ + { placeId: "place1", weight: 1, type: "standard" as const }, + ], outputArcs: [], lambdaCode: `export default Lambda((input) => {\n const t = input.Source[0];\n return t.`, }, diff --git a/libs/@hashintel/petrinaut/src/simulation/simulator/build-simulation.test.ts b/libs/@hashintel/petrinaut/src/simulation/simulator/build-simulation.test.ts index b06c6fbb6e3..616cccc5fec 100644 --- a/libs/@hashintel/petrinaut/src/simulation/simulator/build-simulation.test.ts +++ b/libs/@hashintel/petrinaut/src/simulation/simulator/build-simulation.test.ts @@ -158,8 +158,8 @@ describe("buildSimulation", () => { { id: "t1", name: "Transition 1", - inputArcs: [{ placeId: "p1", weight: 1 }], - outputArcs: [{ placeId: "p2", weight: 1 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "p2", weight: 1, type: "standard" }], lambdaType: "stochastic", lambdaCode: "export default Lambda((tokens) => { return 1.0; });", transitionKernelCode: @@ -170,8 +170,8 @@ describe("buildSimulation", () => { { id: "t2", name: "Transition 2", - inputArcs: [{ placeId: "p2", weight: 1 }], - outputArcs: [{ placeId: "p3", weight: 1 }], + inputArcs: [{ placeId: "p2", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "p3", weight: 1, type: "standard" }], lambdaType: "stochastic", lambdaCode: "export default Lambda((tokens) => { return 2.0; });", transitionKernelCode: diff --git a/libs/@hashintel/petrinaut/src/simulation/simulator/check-transition-enablement.test.ts b/libs/@hashintel/petrinaut/src/simulation/simulator/check-transition-enablement.test.ts index f82115f3983..ec4370a3ff8 100644 --- a/libs/@hashintel/petrinaut/src/simulation/simulator/check-transition-enablement.test.ts +++ b/libs/@hashintel/petrinaut/src/simulation/simulator/check-transition-enablement.test.ts @@ -22,7 +22,7 @@ describe("isTransitionStructurallyEnabled", () => { instance: { id: "t1", name: "Transition 1", - inputArcs: [{ placeId: "p1", weight: 1 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], outputArcs: [], lambdaType: "stochastic", lambdaCode: "return 1.0;", @@ -56,7 +56,7 @@ describe("isTransitionStructurallyEnabled", () => { instance: { id: "t1", name: "Transition 1", - inputArcs: [{ placeId: "p1", weight: 1 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], outputArcs: [], lambdaType: "stochastic", lambdaCode: "return 1.0;", @@ -90,7 +90,7 @@ describe("isTransitionStructurallyEnabled", () => { instance: { id: "t1", name: "Transition 1", - inputArcs: [{ placeId: "p1", weight: 3 }], // Requires 3 tokens + inputArcs: [{ placeId: "p1", weight: 3, type: "standard" }], // Requires 3 tokens outputArcs: [], lambdaType: "stochastic", lambdaCode: "return 1.0;", @@ -131,8 +131,8 @@ describe("isTransitionStructurallyEnabled", () => { id: "t1", name: "Transition 1", inputArcs: [ - { placeId: "p1", weight: 1 }, - { placeId: "p2", weight: 1 }, + { placeId: "p1", weight: 1, type: "standard" }, + { placeId: "p2", weight: 1, type: "standard" }, ], outputArcs: [], lambdaType: "stochastic", @@ -163,7 +163,7 @@ describe("isTransitionStructurallyEnabled", () => { id: "t1", name: "Transition 1", inputArcs: [], // No input arcs - outputArcs: [{ placeId: "p1", weight: 1 }], + outputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], lambdaType: "stochastic", lambdaCode: "return 1.0;", transitionKernelCode: "return {};", @@ -203,7 +203,7 @@ describe("checkTransitionEnablement", () => { instance: { id: "t1", name: "Transition 1", - inputArcs: [{ placeId: "p1", weight: 1 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], outputArcs: [], lambdaType: "stochastic", lambdaCode: "return 1.0;", @@ -219,7 +219,7 @@ describe("checkTransitionEnablement", () => { instance: { id: "t2", name: "Transition 2", - inputArcs: [{ placeId: "p2", weight: 1 }], + inputArcs: [{ placeId: "p2", weight: 1, type: "standard" }], outputArcs: [], lambdaType: "stochastic", lambdaCode: "return 1.0;", @@ -262,7 +262,7 @@ describe("checkTransitionEnablement", () => { instance: { id: "t1", name: "Transition 1", - inputArcs: [{ placeId: "p1", weight: 1 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], outputArcs: [], lambdaType: "stochastic", lambdaCode: "return 1.0;", @@ -278,7 +278,7 @@ describe("checkTransitionEnablement", () => { instance: { id: "t2", name: "Transition 2", - inputArcs: [{ placeId: "p2", weight: 1 }], + inputArcs: [{ placeId: "p2", weight: 1, type: "standard" }], outputArcs: [], lambdaType: "stochastic", lambdaCode: "return 1.0;", @@ -333,7 +333,7 @@ describe("checkTransitionEnablement", () => { instance: { id: "t1", name: "Transition 1", - inputArcs: [{ placeId: "p1", weight: 1 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], outputArcs: [], lambdaType: "stochastic", lambdaCode: "return 1.0;", @@ -349,7 +349,7 @@ describe("checkTransitionEnablement", () => { instance: { id: "t2", name: "Transition 2", - inputArcs: [{ placeId: "p1", weight: 2 }], + inputArcs: [{ placeId: "p1", weight: 2, type: "standard" }], outputArcs: [], lambdaType: "stochastic", lambdaCode: "return 1.0;", @@ -365,7 +365,7 @@ describe("checkTransitionEnablement", () => { instance: { id: "t3", name: "Transition 3", - inputArcs: [{ placeId: "p1", weight: 5 }], + inputArcs: [{ placeId: "p1", weight: 5, type: "standard" }], outputArcs: [], lambdaType: "stochastic", lambdaCode: "return 1.0;", diff --git a/libs/@hashintel/petrinaut/src/simulation/simulator/compute-next-frame.test.ts b/libs/@hashintel/petrinaut/src/simulation/simulator/compute-next-frame.test.ts index 3780808e6c5..32bc61855a0 100644 --- a/libs/@hashintel/petrinaut/src/simulation/simulator/compute-next-frame.test.ts +++ b/libs/@hashintel/petrinaut/src/simulation/simulator/compute-next-frame.test.ts @@ -44,8 +44,8 @@ describe("computeNextFrame", () => { { id: "t1", name: "Transition 1", - inputArcs: [{ placeId: "p1", weight: 1 }], - outputArcs: [{ placeId: "p1", weight: 1 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], lambdaType: "stochastic", lambdaCode: "export default Lambda((tokens, parameters) => { return 0.0001; });", // Very low probability diff --git a/libs/@hashintel/petrinaut/src/simulation/simulator/compute-possible-transition.test.ts b/libs/@hashintel/petrinaut/src/simulation/simulator/compute-possible-transition.test.ts index 9ad5ac6b424..209cbf8ca1d 100644 --- a/libs/@hashintel/petrinaut/src/simulation/simulator/compute-possible-transition.test.ts +++ b/libs/@hashintel/petrinaut/src/simulation/simulator/compute-possible-transition.test.ts @@ -35,7 +35,7 @@ describe("computePossibleTransition", () => { instance: { id: "t1", name: "Transition 1", - inputArcs: [{ placeId: "p1", weight: 2 }], // Requires 2 tokens + inputArcs: [{ placeId: "p1", weight: 2, type: "standard" }], // Requires 2 tokens outputArcs: [], lambdaType: "stochastic", lambdaCode: "return 1.0;", @@ -140,8 +140,8 @@ describe("computePossibleTransition", () => { instance: { id: "t1", name: "Transition 1", - inputArcs: [{ placeId: "p1", weight: 1 }], // Requires 1 token - outputArcs: [{ placeId: "p2", weight: 1 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], // Requires 1 token + outputArcs: [{ placeId: "p2", weight: 1, type: "standard" }], lambdaType: "stochastic", lambdaCode: "return 10.0;", transitionKernelCode: "return [[[2.0]]];", diff --git a/libs/@hashintel/petrinaut/src/simulation/simulator/execute-transitions.test.ts b/libs/@hashintel/petrinaut/src/simulation/simulator/execute-transitions.test.ts index 89a999e023e..a482bbedae8 100644 --- a/libs/@hashintel/petrinaut/src/simulation/simulator/execute-transitions.test.ts +++ b/libs/@hashintel/petrinaut/src/simulation/simulator/execute-transitions.test.ts @@ -34,8 +34,8 @@ describe("executeTransitions", () => { instance: { id: "t1", name: "Transition 1", - inputArcs: [{ placeId: "p1", weight: 1 }], - outputArcs: [{ placeId: "p2", weight: 1 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "p2", weight: 1, type: "standard" }], lambdaType: "stochastic", lambdaCode: "return 1.0;", transitionKernelCode: "return [[[1.0]]];", @@ -134,8 +134,8 @@ describe("executeTransitions", () => { instance: { id: "t1", name: "Transition 1", - inputArcs: [{ placeId: "p1", weight: 1 }], - outputArcs: [{ placeId: "p2", weight: 1 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "p2", weight: 1, type: "standard" }], lambdaType: "stochastic", lambdaCode: "return 10.0;", transitionKernelCode: "return [[[2.0]]];", @@ -270,8 +270,8 @@ describe("executeTransitions", () => { instance: { id: "t1", name: "Transition 1", - inputArcs: [{ placeId: "p1", weight: 1 }], - outputArcs: [{ placeId: "p2", weight: 1 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "p2", weight: 1, type: "standard" }], lambdaType: "stochastic", lambdaCode: "return 10.0;", transitionKernelCode: "return [[[5.0]]];", @@ -286,8 +286,8 @@ describe("executeTransitions", () => { instance: { id: "t2", name: "Transition 2", - inputArcs: [{ placeId: "p1", weight: 1 }], - outputArcs: [{ placeId: "p3", weight: 1 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "p3", weight: 1, type: "standard" }], lambdaType: "stochastic", lambdaCode: "return 10.0;", transitionKernelCode: "return [[[10.0]]];", @@ -406,8 +406,8 @@ describe("executeTransitions", () => { instance: { id: "t1", name: "Transition 1", - inputArcs: [{ placeId: "p1", weight: 1 }], - outputArcs: [{ placeId: "p2", weight: 1 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "p2", weight: 1, type: "standard" }], lambdaType: "stochastic", lambdaCode: "return 10.0;", transitionKernelCode: "return [[[3.0, 4.0]]];", @@ -518,8 +518,8 @@ describe("executeTransitions", () => { instance: { id: "t1", name: "Transition 1", - inputArcs: [{ placeId: "p1", weight: 1 }], - outputArcs: [{ placeId: "p2", weight: 1 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "p2", weight: 1, type: "standard" }], lambdaType: "stochastic", lambdaCode: "return 10.0;", transitionKernelCode: "return [[[2.0]]];", @@ -534,8 +534,8 @@ describe("executeTransitions", () => { instance: { id: "t2", name: "Transition 2", - inputArcs: [{ placeId: "p1", weight: 1 }], - outputArcs: [{ placeId: "p2", weight: 1 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "p2", weight: 1, type: "standard" }], lambdaType: "stochastic", lambdaCode: "return 0.001;", transitionKernelCode: "return [[[3.0]]];", diff --git a/libs/@hashintel/petrinaut/src/state/mutation-provider.test.tsx b/libs/@hashintel/petrinaut/src/state/mutation-provider.test.tsx index e7429dbadcf..d311da891d6 100644 --- a/libs/@hashintel/petrinaut/src/state/mutation-provider.test.tsx +++ b/libs/@hashintel/petrinaut/src/state/mutation-provider.test.tsx @@ -435,8 +435,8 @@ describe("MutationProvider", () => { { id: "t1", name: "T1", - inputArcs: [{ placeId: "p1", weight: 1 }], - outputArcs: [{ placeId: "p2", weight: 1 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "p2", weight: 1, type: "standard" }], lambdaType: "predicate", lambdaCode: "", transitionKernelCode: "", @@ -555,8 +555,8 @@ describe("MutationProvider", () => { { id: "t1", name: "T1", - inputArcs: [{ placeId: "p1", weight: 1 }], - outputArcs: [{ placeId: "p2", weight: 1 }], + inputArcs: [{ placeId: "p1", weight: 1, type: "standard" }], + outputArcs: [{ placeId: "p2", weight: 1, type: "standard" }], lambdaType: "predicate", lambdaCode: "", transitionKernelCode: "", diff --git a/libs/@hashintel/petrinaut/src/state/mutation-provider.tsx b/libs/@hashintel/petrinaut/src/state/mutation-provider.tsx index e5514bf3961..0f3186d7832 100644 --- a/libs/@hashintel/petrinaut/src/state/mutation-provider.tsx +++ b/libs/@hashintel/petrinaut/src/state/mutation-provider.tsx @@ -127,6 +127,7 @@ export const MutationProvider: React.FC = ({ for (const transition of sdcpn.transitions) { if (transition.id === transitionId) { transition[arcType === "input" ? "inputArcs" : "outputArcs"].push({ + type: "standard", placeId, weight, }); diff --git a/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/properties-panel.stories.tsx b/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/properties-panel.stories.tsx index 38a2d5a8c1b..a4bd6ccb0da 100644 --- a/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/properties-panel.stories.tsx +++ b/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/properties-panel.stories.tsx @@ -106,10 +106,10 @@ const TRANSITION: Transition = { id: "transition-1", name: "ProcessOrder", inputArcs: [ - { placeId: "place-1", weight: 1 }, - { placeId: "place-2", weight: 2 }, + { placeId: "place-1", weight: 1, type: "standard" }, + { placeId: "place-2", weight: 2, type: "standard" }, ], - outputArcs: [{ placeId: "place-3", weight: 1 }], + outputArcs: [{ placeId: "place-3", weight: 1, type: "standard" }], lambdaType: "predicate", lambdaCode: "function predicate(inputs) {\n return true;\n}", transitionKernelCode: "function kernel(inputs) {\n return inputs;\n}", diff --git a/libs/@hashintel/petrinaut/src/views/SDCPN/hooks/use-sdcpn-to-react-flow.ts b/libs/@hashintel/petrinaut/src/views/SDCPN/hooks/use-sdcpn-to-react-flow.ts index cebec1c1e82..32a94118e58 100644 --- a/libs/@hashintel/petrinaut/src/views/SDCPN/hooks/use-sdcpn-to-react-flow.ts +++ b/libs/@hashintel/petrinaut/src/views/SDCPN/hooks/use-sdcpn-to-react-flow.ts @@ -125,6 +125,7 @@ export function useSdcpnToReactFlow(): PetrinautReactFlowDefinitionObject { source: inputArc.placeId, target: transition.id, type: "default" as const, + arcType: inputArc.type, selected: isSelected(arcId), markerEnd: { type: MarkerType.ArrowClosed, @@ -166,6 +167,7 @@ export function useSdcpnToReactFlow(): PetrinautReactFlowDefinitionObject { source: transition.id, target: outputArc.placeId, type: "default" as const, + arcType: outputArc.type, selected: isSelected(arcId), markerEnd: { type: MarkerType.ArrowClosed, From 65252b9cace0fe44745ecb9634a9b0520dde2ccf Mon Sep 17 00:00:00 2001 From: alex leon Date: Thu, 9 Apr 2026 17:20:26 +0200 Subject: [PATCH 02/17] Rename arcType to arcDirection in petrinaut --- .../petrinaut/src/state/mutation-context.ts | 6 ++--- .../petrinaut/src/state/mutation-provider.tsx | 16 ++++++++------ .../PropertiesPanel/arc-properties/main.tsx | 22 +++++++++---------- .../properties-panel.stories.tsx | 5 +++-- .../transition-properties/context.tsx | 4 ++-- .../transition-properties/main.tsx | 2 +- 6 files changed, 29 insertions(+), 26 deletions(-) diff --git a/libs/@hashintel/petrinaut/src/state/mutation-context.ts b/libs/@hashintel/petrinaut/src/state/mutation-context.ts index b0d981c2df3..103a674d18e 100644 --- a/libs/@hashintel/petrinaut/src/state/mutation-context.ts +++ b/libs/@hashintel/petrinaut/src/state/mutation-context.ts @@ -29,18 +29,18 @@ export type MutationHelperFunctions = { removeTransition: (transitionId: string) => void; addArc: ( transitionId: string, - arcType: "input" | "output", + arcDirection: "input" | "output", placeId: string, weight: number, ) => void; removeArc: ( transitionId: string, - arcType: "input" | "output", + arcDirection: "input" | "output", placeId: string, ) => void; updateArcWeight: ( transitionId: string, - arcType: "input" | "output", + arcDirection: "input" | "output", placeId: string, weight: number, ) => void; diff --git a/libs/@hashintel/petrinaut/src/state/mutation-provider.tsx b/libs/@hashintel/petrinaut/src/state/mutation-provider.tsx index 0f3186d7832..b1858f31a05 100644 --- a/libs/@hashintel/petrinaut/src/state/mutation-provider.tsx +++ b/libs/@hashintel/petrinaut/src/state/mutation-provider.tsx @@ -122,11 +122,13 @@ export const MutationProvider: React.FC = ({ } }); }, - addArc(transitionId, arcType, placeId, weight) { + addArc(transitionId, arcDirection, placeId, weight) { guardedMutate((sdcpn) => { for (const transition of sdcpn.transitions) { if (transition.id === transitionId) { - transition[arcType === "input" ? "inputArcs" : "outputArcs"].push({ + transition[ + arcDirection === "input" ? "inputArcs" : "outputArcs" + ].push({ type: "standard", placeId, weight, @@ -136,16 +138,16 @@ export const MutationProvider: React.FC = ({ } }); }, - removeArc(transitionId, arcType, placeId) { + removeArc(transitionId, arcDirection, placeId) { guardedMutate((sdcpn) => { for (const transition of sdcpn.transitions) { if (transition.id === transitionId) { for (const [index, arc] of transition[ - arcType === "input" ? "inputArcs" : "outputArcs" + arcDirection === "input" ? "inputArcs" : "outputArcs" ].entries()) { if (arc.placeId === placeId) { transition[ - arcType === "input" ? "inputArcs" : "outputArcs" + arcDirection === "input" ? "inputArcs" : "outputArcs" ].splice(index, 1); break; } @@ -155,12 +157,12 @@ export const MutationProvider: React.FC = ({ } }); }, - updateArcWeight(transitionId, arcType, placeId, weight) { + updateArcWeight(transitionId, arcDirection, placeId, weight) { guardedMutate((sdcpn) => { for (const transition of sdcpn.transitions) { if (transition.id === transitionId) { for (const arc of transition[ - arcType === "input" ? "inputArcs" : "outputArcs" + arcDirection === "input" ? "inputArcs" : "outputArcs" ]) { if (arc.placeId === placeId) { arc.weight = weight; diff --git a/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/arc-properties/main.tsx b/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/arc-properties/main.tsx index 4e15f057c0f..6eca7ed1c34 100644 --- a/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/arc-properties/main.tsx +++ b/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/arc-properties/main.tsx @@ -31,19 +31,19 @@ interface ArcPropertiesData { arcId: string; transitionId: string; placeId: string; - arcType: "input" | "output"; + arcDirection: "input" | "output"; sourceName: string; targetName: string; weight: number; updateArcWeight: ( transitionId: string, - arcType: "input" | "output", + arcDirection: "input" | "output", placeId: string, weight: number, ) => void; removeArc: ( transitionId: string, - arcType: "input" | "output", + arcDirection: "input" | "output", placeId: string, ) => void; } @@ -64,7 +64,7 @@ const ArcMainContent: React.FC = () => { const { transitionId, placeId, - arcType, + arcDirection, sourceName, targetName, weight, @@ -92,7 +92,7 @@ const ArcMainContent: React.FC = () => { 10, ); if (value > 0) { - updateArcWeight(transitionId, arcType, placeId, value); + updateArcWeight(transitionId, arcDirection, placeId, value); } }} disabled={isReadOnly} @@ -103,7 +103,7 @@ const ArcMainContent: React.FC = () => { }; const DeleteArcAction: React.FC = () => { - const { transitionId, placeId, arcType, removeArc } = + const { transitionId, placeId, arcDirection, removeArc } = useArcPropertiesContext(); const { clearSelection } = use(EditorContext); const isReadOnly = useIsReadOnly(); @@ -114,7 +114,7 @@ const DeleteArcAction: React.FC = () => { size="xs" colorScheme="red" onClick={() => { - removeArc(transitionId, arcType, placeId); + removeArc(transitionId, arcDirection, placeId); clearSelection(); }} disabled={isReadOnly} @@ -142,13 +142,13 @@ interface ArcPropertiesProps { petriNetDefinition: SDCPN; updateArcWeight: ( transitionId: string, - arcType: "input" | "output", + arcDirection: "input" | "output", placeId: string, weight: number, ) => void; removeArc: ( transitionId: string, - arcType: "input" | "output", + arcDirection: "input" | "output", placeId: string, ) => void; } @@ -189,7 +189,7 @@ export const ArcProperties: React.FC = ({ arcId, transitionId: targetTransition.id, placeId: sourcePlace.id, - arcType: "input", + arcDirection: "input", sourceName: sourcePlace.name, targetName: targetTransition.name, weight: arc?.weight ?? 1, @@ -204,7 +204,7 @@ export const ArcProperties: React.FC = ({ arcId, transitionId: sourceTransition.id, placeId: targetPlace.id, - arcType: "output", + arcDirection: "output", sourceName: sourceTransition.name, targetName: targetPlace.name, weight: arc?.weight ?? 1, diff --git a/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/properties-panel.stories.tsx b/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/properties-panel.stories.tsx index a4bd6ccb0da..ded306ce805 100644 --- a/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/properties-panel.stories.tsx +++ b/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/properties-panel.stories.tsx @@ -246,9 +246,10 @@ const TransitionPanelStory = () => { places={PLACES} types={TYPES} updateTransition={updateTransition} - onArcWeightUpdate={(transitionId, arcType, placeId, weight) => { + onArcWeightUpdate={(transitionId, arcDirection, placeId, weight) => { updateTransition(transitionId, (tr) => { - const arcs = arcType === "input" ? tr.inputArcs : tr.outputArcs; + const arcs = + arcDirection === "input" ? tr.inputArcs : tr.outputArcs; const arc = arcs.find((a) => a.placeId === placeId); if (arc) { arc.weight = weight; diff --git a/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/transition-properties/context.tsx b/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/transition-properties/context.tsx index ad091b186ca..d6afc76aa5b 100644 --- a/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/transition-properties/context.tsx +++ b/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/transition-properties/context.tsx @@ -13,7 +13,7 @@ interface TransitionPropertiesContextValue { ) => void; onArcWeightUpdate: ( transitionId: string, - arcType: "input" | "output", + arcDirection: "input" | "output", placeId: string, weight: number, ) => void; @@ -44,7 +44,7 @@ interface TransitionPropertiesProviderProps { ) => void; onArcWeightUpdate: ( transitionId: string, - arcType: "input" | "output", + arcDirection: "input" | "output", placeId: string, weight: number, ) => void; diff --git a/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/transition-properties/main.tsx b/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/transition-properties/main.tsx index 81ae1267566..d951f4af190 100644 --- a/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/transition-properties/main.tsx +++ b/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/transition-properties/main.tsx @@ -26,7 +26,7 @@ interface TransitionPropertiesProps { ) => void; onArcWeightUpdate: ( transitionId: string, - arcType: "input" | "output", + arcDirection: "input" | "output", placeId: string, weight: number, ) => void; From 6d474e0c12bd13b475f377f733fa869304bca056 Mon Sep 17 00:00:00 2001 From: alex leon Date: Thu, 9 Apr 2026 18:22:48 +0200 Subject: [PATCH 03/17] Add select form field to panel for arc type --- .../petrinaut/src/state/mutation-context.ts | 7 ++++ .../petrinaut/src/state/mutation-provider.tsx | 17 ++++++++ .../PropertiesPanel/arc-properties/main.tsx | 41 +++++++++++++++++++ .../Editor/panels/PropertiesPanel/panel.tsx | 2 + 4 files changed, 67 insertions(+) diff --git a/libs/@hashintel/petrinaut/src/state/mutation-context.ts b/libs/@hashintel/petrinaut/src/state/mutation-context.ts index 103a674d18e..b1a80846141 100644 --- a/libs/@hashintel/petrinaut/src/state/mutation-context.ts +++ b/libs/@hashintel/petrinaut/src/state/mutation-context.ts @@ -44,6 +44,12 @@ export type MutationHelperFunctions = { placeId: string, weight: number, ) => void; + updateArcType: ( + transitionId: string, + arcDirection: "input" | "output", + placeId: string, + type: "standard" | "inhibitor", + ) => void; addType: (type: Color) => void; updateType: (typeId: string, updateFn: (type: Color) => void) => void; removeType: (typeId: string) => void; @@ -85,6 +91,7 @@ const DEFAULT_CONTEXT_VALUE: MutationContextValue = { addArc: () => {}, removeArc: () => {}, updateArcWeight: () => {}, + updateArcType: () => {}, addType: () => {}, updateType: () => {}, removeType: () => {}, diff --git a/libs/@hashintel/petrinaut/src/state/mutation-provider.tsx b/libs/@hashintel/petrinaut/src/state/mutation-provider.tsx index b1858f31a05..4f53e8319ec 100644 --- a/libs/@hashintel/petrinaut/src/state/mutation-provider.tsx +++ b/libs/@hashintel/petrinaut/src/state/mutation-provider.tsx @@ -174,6 +174,23 @@ export const MutationProvider: React.FC = ({ } }); }, + updateArcType(transitionId, arcDirection, placeId, type) { + guardedMutate((sdcpn) => { + for (const transition of sdcpn.transitions) { + if (transition.id === transitionId) { + for (const arc of transition[ + arcDirection === "input" ? "inputArcs" : "outputArcs" + ]) { + if (arc.placeId === placeId) { + arc.type = type; + break; + } + } + break; + } + } + }); + }, addType(type) { guardedMutate((sdcpn) => { sdcpn.types.push(type); diff --git a/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/arc-properties/main.tsx b/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/arc-properties/main.tsx index 6eca7ed1c34..fb7a7ca8b73 100644 --- a/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/arc-properties/main.tsx +++ b/libs/@hashintel/petrinaut/src/views/Editor/panels/PropertiesPanel/arc-properties/main.tsx @@ -6,6 +6,8 @@ import { TbTrash } from "react-icons/tb"; import { IconButton } from "../../../../../components/icon-button"; import { NumberInput } from "../../../../../components/number-input"; import { Section, SectionList } from "../../../../../components/section"; +import { Switch } from "../../../../../components/switch"; +import { Select, type SelectOption } from "../../../../../components/select"; import type { SubView } from "../../../../../components/sub-view/types"; import { VerticalSubViewsContainer } from "../../../../../components/sub-view/vertical/vertical-sub-views-container"; import { UI_MESSAGES } from "../../../../../constants/ui-messages"; @@ -35,12 +37,19 @@ interface ArcPropertiesData { sourceName: string; targetName: string; weight: number; + type: "standard" | "inhibitor"; updateArcWeight: ( transitionId: string, arcDirection: "input" | "output", placeId: string, weight: number, ) => void; + updateArcType: ( + transitionId: string, + arcDirection: "input" | "output", + placeId: string, + type: "standard" | "inhibitor", + ) => void; removeArc: ( transitionId: string, arcDirection: "input" | "output", @@ -68,7 +77,9 @@ const ArcMainContent: React.FC = () => { sourceName, targetName, weight, + type, updateArcWeight, + updateArcType, } = useArcPropertiesContext(); const isReadOnly = useIsReadOnly(); @@ -80,6 +91,25 @@ const ArcMainContent: React.FC = () => {
{targetName}
+
+ { - updateArcType( - transitionId, - placeId, - value as "inhibitor" | "standard", - ); - }} - options={[ - { value: "standard", label: "Standard" }, - { value: "inhibitor", label: "Inhibitor" }, - ]} - disabled={isReadOnly} - tooltip={isReadOnly ? UI_MESSAGES.READ_ONLY_MODE : undefined} - /> -
+ {arcDirection === "input" && ( +
+