Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
51d36c0
Fix token count display in PlaceNode inside SDCPNView
kube Jan 15, 2026
2a6c48e
Use tabular nums to preserve width of token count badge
kube Jan 15, 2026
ee70bbf
Bit of cleanup
kube Jan 15, 2026
3687ff6
Remove unused types-for-editor-to-remove.ts and update imports in SDC…
kube Jan 15, 2026
eb9cae3
Refactor useSdcpnToReactFlow to utilize petriNetDefinition directly, …
kube Jan 15, 2026
9e478a0
Enhance simulation context and provider: Introduce SimulationFrameSta…
kube Jan 16, 2026
d838a65
Simplify Arcs weight
kube Jan 16, 2026
024497d
Update ReactFlow types
kube Jan 16, 2026
520c07d
Fix type in useSdcnToReactFlow
kube Jan 18, 2026
07ef29a
Reorganize Simulation stuff inside a simulation/ folder
kube Jan 18, 2026
8499967
Format/lint
kube Jan 18, 2026
69a6d30
Remove SimulationFrameStateDiff and add firingCount to SimulationFram…
kube Jan 18, 2026
334cad3
Add firingCount to ArcData
kube Jan 18, 2026
a37d5f8
Add useFiringDelta
kube Jan 18, 2026
3fe41c3
Update
kube Jan 18, 2026
474503b
Add firingCount and compute firingDelta in Arc and TransitionNode
kube Jan 19, 2026
7f64fd5
Expose justFired on SimulationFrame
kube Jan 19, 2026
802cfa3
Add justFired to Simulation context and provider
kube Jan 19, 2026
7980d3a
Arc animation uses weight
kube Jan 19, 2026
6e3b0e9
Do not cancel Arc firing animation when next frame does not have one …
kube Jan 19, 2026
73a196e
Cumulate arc firing animations
kube Jan 19, 2026
d03a6e0
Remove useless line in JSDoc
kube Jan 19, 2026
de8d85f
Use logarighmic scale for strokeWidth
kube Jan 19, 2026
0a03f61
Multiply peakStrokeWidth by 3
kube Jan 19, 2026
4245d42
Add DashArray animation
kube Jan 19, 2026
96e310a
Enhance TransitionNode with firing animation and refactor styles. Int…
kube Jan 20, 2026
8ecc8cb
Lint
kube Jan 20, 2026
99a7582
Lint
kube Jan 20, 2026
ff2e129
Remove animation of strokeDashArray/Offset
kube Jan 20, 2026
64c6d11
Add changeset
kube Jan 20, 2026
719e779
Fix frame info display
kube Jan 20, 2026
6387aa2
Refactor simulation transition state management. Updated transition p…
kube Jan 20, 2026
b2b19ba
Refactor simulation types by consolidating definitions in the context…
kube Jan 20, 2026
94f2d6c
Fix missing color tokens
kube Jan 21, 2026
5518ca8
Add back unit tests as they could be useful even if need rework later
kube Jan 21, 2026
27921c8
fix(petrinaut): prevent spurious animation on initial mount
kube Jan 21, 2026
a6276a2
fix(petrinaut): restore BaseEdge for edge interaction handling
kube Jan 21, 2026
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
5 changes: 5 additions & 0 deletions .changeset/rotten-lemons-sparkle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hashintel/petrinaut": patch
---

Better animation of Transitions and flow inside Arcs
61 changes: 0 additions & 61 deletions libs/@hashintel/petrinaut/src/core/types/simulation.ts

This file was deleted.

2 changes: 1 addition & 1 deletion libs/@hashintel/petrinaut/src/petrinaut.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import type {
} from "./core/types/sdcpn";
import { useMonacoGlobalTypings } from "./hooks/use-monaco-global-typings";
import { NotificationsProvider } from "./notifications/notifications-provider";
import { SimulationProvider } from "./simulation/provider";
import { CheckerProvider } from "./state/checker-provider";
import { EditorProvider } from "./state/editor-provider";
import { SDCPNProvider } from "./state/sdcpn-provider";
import { SimulationProvider } from "./state/simulation-provider";
import { EditorView } from "./views/Editor/editor-view";

export type {
Expand Down
252 changes: 252 additions & 0 deletions libs/@hashintel/petrinaut/src/simulation/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
import { createContext } from "react";

import type { Color, ID, Place, SDCPN, Transition } from "../core/types/sdcpn";

/**
* Current state of the simulation lifecycle.
*/
export type SimulationState =
| "NotRun"
| "Running"
| "Complete"
| "Error"
| "Paused";

/**
* State of a transition within a simulation frame.
*
* Contains timing information and firing counts for tracking transition behavior
* during simulation execution.
*/
export type SimulationFrameState_Transition = {
/**
* Time elapsed since this transition last fired, in milliseconds.
* Resets to 0 when the transition fires.
*/
timeSinceLastFiringMs: number;
/**
* Whether this transition fired in this specific frame.
* True only during the frame when the firing occurred.
*/
firedInThisFrame: boolean;
/**
* Total cumulative count of times this transition has fired
* since the start of the simulation (frame 0).
*/
firingCount: number;
};

//
// Simulation Instance Types
//
// These types define the internal simulation data structures. They are defined
// here to ensure the context module has no dependencies on the simulator module,
// making the context the source of truth for type definitions.
//
// TODO FE-207: This is a temporary solution that leaks implementation details of the
// SDCPN simulator (e.g., compiled function types, buffer layouts) into the
// context module. Ideally, the context should only expose a minimal public
// interface, and these internal types should live in the simulator module.
// This would require refactoring SimulationContextValue to not expose the
// full SimulationInstance, but instead provide accessor methods or a
// simplified public state type.
//

/**
* Runtime parameter values used during simulation execution.
* Maps parameter names to their resolved numeric or boolean values.
*/
export type ParameterValues = Record<string, number | boolean>;

/**
* Compiled differential equation function for continuous dynamics.
* Computes the rate of change for tokens in a place with dynamics enabled.
*/
export type DifferentialEquationFn = (
tokens: Record<string, number>[],
parameters: ParameterValues,
) => Record<string, number>[];

/**
* Compiled lambda function for transition firing probability.
* Returns a rate (number) for stochastic transitions or a boolean for predicate transitions.
*/
export type LambdaFn = (
tokenValues: Record<string, Record<string, number>[]>,
parameters: ParameterValues,
) => number | boolean;

/**
* Compiled transition kernel function for token generation.
* Computes the output tokens to create when a transition fires.
*/
export type TransitionKernelFn = (
tokenValues: Record<string, Record<string, number>[]>,
parameters: ParameterValues,
) => Record<string, Record<string, number>[]>;

/**
* Input configuration for building a new simulation instance.
*/
export type SimulationInput = {
/** The SDCPN definition to simulate */
sdcpn: SDCPN;
/** Initial token distribution across places */
initialMarking: Map<string, { values: Float64Array; count: number }>;
/** Parameter values from the simulation store (overrides SDCPN defaults) */
parameterValues: Record<string, string>;
/** Random seed for deterministic stochastic behavior */
seed: number;
/** Time step for simulation advancement */
dt: number;
};

/**
* A running simulation instance with compiled functions and frame history.
* Contains all state needed to execute and advance the simulation.
*/
export type SimulationInstance = {
/** Place definitions indexed by ID */
places: Map<string, Place>;
/** Transition definitions indexed by ID */
transitions: Map<string, Transition>;
/** Color type definitions indexed by ID */
types: Map<string, Color>;
/** Compiled differential equation functions indexed by place ID */
differentialEquationFns: Map<string, DifferentialEquationFn>;
/** Compiled lambda functions indexed by transition ID */
lambdaFns: Map<string, LambdaFn>;
/** Compiled transition kernel functions indexed by transition ID */
transitionKernelFns: Map<string, TransitionKernelFn>;
/** Resolved parameter values for this simulation run */
parameterValues: ParameterValues;
/** Time step for simulation advancement */
dt: number;
/** Current state of the seeded random number generator */
rngState: number;
/** History of all computed frames */
frames: SimulationFrame[];
/** Index of the current frame in the frames array */
currentFrameNumber: number;
};

/**
* A single frame (snapshot) of the simulation state at a point in time.
* Contains the complete token distribution and transition states.
*/
export type SimulationFrame = {
/** Back-reference to the parent simulation instance */
simulation: SimulationInstance;
/** Simulation time at this frame */
time: number;
/** Place states with token buffer offsets */
places: Map<
ID,
{ instance: Place; offset: number; count: number; dimensions: number }
>;
/** Transition states with firing information */
transitions: Map<
ID,
SimulationFrameState_Transition & { instance: Transition }
>;
/**
* Buffer containing all place values concatenated.
*
* Size: sum of (place.dimensions * place.count) for all places.
*
* Layout: For each place, its tokens are stored contiguously.
*
* Access to a place's token values can be done via the offset and count in the `places` map.
*/
buffer: Float64Array;
};

/**
* Simplified view of a simulation frame for UI consumption.
* Provides easy access to place and transition states without internal details.
*/
export type SimulationFrameState = {
/** Frame index in the simulation history */
number: number;
/** Simulation time at this frame */
time: number;
/** Place states indexed by place ID */
places: {
[placeId: string]:
| {
/** Number of tokens in the place at the time of the frame. */
tokenCount: number;
}
| undefined;
};
/** Transition states indexed by transition ID */
transitions: {
[transitionId: string]: SimulationFrameState_Transition | undefined;
};
};

/**
* Initial token distribution for starting a simulation.
* Maps place IDs to their initial token values and counts.
*/
export type InitialMarking = Map<
string,
{ values: Float64Array; count: number }
>;

/**
* The combined simulation context containing both state and actions.
*/
export type SimulationContextValue = {
// State values
simulation: SimulationInstance | null;
state: SimulationState;
error: string | null;
errorItemId: string | null;
parameterValues: Record<string, string>;
initialMarking: InitialMarking;
/**
* The currently viewed simulation frame state.
* Null when no simulation is running or no frames exist.
*/
currentViewedFrame: SimulationFrameState | null;
dt: number;

// Actions
setInitialMarking: (
placeId: string,
marking: { values: Float64Array; count: number },
) => void;
setParameterValue: (parameterId: string, value: string) => void;
setDt: (dt: number) => void;
initializeParameterValuesFromDefaults: () => void;
initialize: (params: { seed: number; dt: number }) => void;
run: () => void;
pause: () => void;
reset: () => void;
setCurrentViewedFrame: (frameIndex: number) => void;
};

const DEFAULT_CONTEXT_VALUE: SimulationContextValue = {
simulation: null,
state: "NotRun",
error: null,
errorItemId: null,
parameterValues: {},
initialMarking: new Map(),
currentViewedFrame: null,
dt: 0.01,
setInitialMarking: () => {},
setParameterValue: () => {},
setDt: () => {},
initializeParameterValuesFromDefaults: () => {},
initialize: () => {},
run: () => {},
pause: () => {},
reset: () => {},
setCurrentViewedFrame: () => {},
};

export const SimulationContext = createContext<SimulationContextValue>(
DEFAULT_CONTEXT_VALUE,
);
Loading
Loading