fsm_core
Overview
| Package | Version | Category | License | Language |
|---|---|---|---|---|
fsm_core | 1.1.0 | FEAT | Apache-2.0 | SQL |
| ID | Extension | Bin | Lib | Load | Create | Trust | Reloc | Schema |
|---|---|---|---|---|---|---|---|---|
| 2690 | fsm_core | No | No | No | Yes | No | No | fsm_core |
| Related | ltree pgmq pg_jsonschema pgmq pg_jsonschema pg_task pg_later pg_cron |
|---|
PG15+; requires ltree, pgmq, and pg_jsonschema
Version
| Type | Repo | Version | PG Ver | Package | Deps |
|---|---|---|---|---|---|
| EXT | PIGSTY | 1.1.0 | 1817161514 | fsm_core | ltree, pgmq, pg_jsonschema |
| RPM | PIGSTY | 1.1.0 | 1817161514 | fsm_core_$v | pgmq_$v |
| DEB | PIGSTY | 1.1.0 | 1817161514 | postgresql-$v-fsm-core | postgresql-$v-pgmq, postgresql-$v-pg-jsonschema |
| OS / PG | PG18 | PG17 | PG16 | PG15 | PG14 |
|---|---|---|---|---|---|
| el8.x86_64 | PIGSTY 1.1.0 el8.x86_64.pg18 : fsm_core_18 fsm_core_18-1.1.0-1PIGSTY.el8.x86_64.rpm
| PIGSTY 1.1.0 el8.x86_64.pg17 : fsm_core_17 fsm_core_17-1.1.0-1PIGSTY.el8.x86_64.rpm
| PIGSTY 1.1.0 el8.x86_64.pg16 : fsm_core_16 fsm_core_16-1.1.0-1PIGSTY.el8.x86_64.rpm
| PIGSTY 1.1.0 el8.x86_64.pg15 : fsm_core_15 fsm_core_15-1.1.0-1PIGSTY.el8.x86_64.rpm
| PIGSTY MISS |
| el8.aarch64 | PIGSTY 1.1.0 el8.aarch64.pg18 : fsm_core_18 fsm_core_18-1.1.0-1PIGSTY.el8.aarch64.rpm
| PIGSTY 1.1.0 el8.aarch64.pg17 : fsm_core_17 fsm_core_17-1.1.0-1PIGSTY.el8.aarch64.rpm
| PIGSTY 1.1.0 el8.aarch64.pg16 : fsm_core_16 fsm_core_16-1.1.0-1PIGSTY.el8.aarch64.rpm
| PIGSTY 1.1.0 el8.aarch64.pg15 : fsm_core_15 fsm_core_15-1.1.0-1PIGSTY.el8.aarch64.rpm
| PIGSTY MISS |
| el9.x86_64 | PIGSTY 1.1.0 el9.x86_64.pg18 : fsm_core_18 fsm_core_18-1.1.0-1PIGSTY.el9.x86_64.rpm
| PIGSTY 1.1.0 el9.x86_64.pg17 : fsm_core_17 fsm_core_17-1.1.0-1PIGSTY.el9.x86_64.rpm
| PIGSTY 1.1.0 el9.x86_64.pg16 : fsm_core_16 fsm_core_16-1.1.0-1PIGSTY.el9.x86_64.rpm
| PIGSTY 1.1.0 el9.x86_64.pg15 : fsm_core_15 fsm_core_15-1.1.0-1PIGSTY.el9.x86_64.rpm
| PIGSTY MISS |
| el9.aarch64 | PIGSTY 1.1.0 el9.aarch64.pg18 : fsm_core_18 fsm_core_18-1.1.0-1PIGSTY.el9.aarch64.rpm
| PIGSTY 1.1.0 el9.aarch64.pg17 : fsm_core_17 fsm_core_17-1.1.0-1PIGSTY.el9.aarch64.rpm
| PIGSTY 1.1.0 el9.aarch64.pg16 : fsm_core_16 fsm_core_16-1.1.0-1PIGSTY.el9.aarch64.rpm
| PIGSTY 1.1.0 el9.aarch64.pg15 : fsm_core_15 fsm_core_15-1.1.0-1PIGSTY.el9.aarch64.rpm
| PIGSTY MISS |
| el10.x86_64 | PIGSTY 1.1.0 el10.x86_64.pg18 : fsm_core_18 fsm_core_18-1.1.0-1PIGSTY.el10.x86_64.rpm
| PIGSTY 1.1.0 el10.x86_64.pg17 : fsm_core_17 fsm_core_17-1.1.0-1PIGSTY.el10.x86_64.rpm
| PIGSTY 1.1.0 el10.x86_64.pg16 : fsm_core_16 fsm_core_16-1.1.0-1PIGSTY.el10.x86_64.rpm
| PIGSTY 1.1.0 el10.x86_64.pg15 : fsm_core_15 fsm_core_15-1.1.0-1PIGSTY.el10.x86_64.rpm
| PIGSTY MISS |
| el10.aarch64 | PIGSTY 1.1.0 el10.aarch64.pg18 : fsm_core_18 fsm_core_18-1.1.0-1PIGSTY.el10.aarch64.rpm
| PIGSTY 1.1.0 el10.aarch64.pg17 : fsm_core_17 fsm_core_17-1.1.0-1PIGSTY.el10.aarch64.rpm
| PIGSTY 1.1.0 el10.aarch64.pg16 : fsm_core_16 fsm_core_16-1.1.0-1PIGSTY.el10.aarch64.rpm
| PIGSTY 1.1.0 el10.aarch64.pg15 : fsm_core_15 fsm_core_15-1.1.0-1PIGSTY.el10.aarch64.rpm
| PIGSTY MISS |
| d12.x86_64 | PIGSTY 1.1.0 d12.x86_64.pg18 : postgresql-18-fsm-core postgresql-18-fsm-core_1.1.0-1PIGSTY~bookworm_all.deb
| PIGSTY 1.1.0 d12.x86_64.pg17 : postgresql-17-fsm-core postgresql-17-fsm-core_1.1.0-1PIGSTY~bookworm_all.deb
| PIGSTY 1.1.0 d12.x86_64.pg16 : postgresql-16-fsm-core postgresql-16-fsm-core_1.1.0-1PIGSTY~bookworm_all.deb
| PIGSTY 1.1.0 d12.x86_64.pg15 : postgresql-15-fsm-core postgresql-15-fsm-core_1.1.0-1PIGSTY~bookworm_all.deb
| PIGSTY MISS |
| d12.aarch64 | PIGSTY 1.1.0 d12.aarch64.pg18 : postgresql-18-fsm-core postgresql-18-fsm-core_1.1.0-1PIGSTY~bookworm_all.deb
| PIGSTY 1.1.0 d12.aarch64.pg17 : postgresql-17-fsm-core postgresql-17-fsm-core_1.1.0-1PIGSTY~bookworm_all.deb
| PIGSTY 1.1.0 d12.aarch64.pg16 : postgresql-16-fsm-core postgresql-16-fsm-core_1.1.0-1PIGSTY~bookworm_all.deb
| PIGSTY 1.1.0 d12.aarch64.pg15 : postgresql-15-fsm-core postgresql-15-fsm-core_1.1.0-1PIGSTY~bookworm_all.deb
| PIGSTY MISS |
| d13.x86_64 | PIGSTY 1.1.0 d13.x86_64.pg18 : postgresql-18-fsm-core postgresql-18-fsm-core_1.1.0-1PIGSTY~trixie_all.deb
| PIGSTY 1.1.0 d13.x86_64.pg17 : postgresql-17-fsm-core postgresql-17-fsm-core_1.1.0-1PIGSTY~trixie_all.deb
| PIGSTY 1.1.0 d13.x86_64.pg16 : postgresql-16-fsm-core postgresql-16-fsm-core_1.1.0-1PIGSTY~trixie_all.deb
| PIGSTY 1.1.0 d13.x86_64.pg15 : postgresql-15-fsm-core postgresql-15-fsm-core_1.1.0-1PIGSTY~trixie_all.deb
| PIGSTY MISS |
| d13.aarch64 | PIGSTY 1.1.0 d13.aarch64.pg18 : postgresql-18-fsm-core postgresql-18-fsm-core_1.1.0-1PIGSTY~trixie_all.deb
| PIGSTY 1.1.0 d13.aarch64.pg17 : postgresql-17-fsm-core postgresql-17-fsm-core_1.1.0-1PIGSTY~trixie_all.deb
| PIGSTY 1.1.0 d13.aarch64.pg16 : postgresql-16-fsm-core postgresql-16-fsm-core_1.1.0-1PIGSTY~trixie_all.deb
| PIGSTY 1.1.0 d13.aarch64.pg15 : postgresql-15-fsm-core postgresql-15-fsm-core_1.1.0-1PIGSTY~trixie_all.deb
| PIGSTY MISS |
| u22.x86_64 | PIGSTY 1.1.0 u22.x86_64.pg18 : postgresql-18-fsm-core postgresql-18-fsm-core_1.1.0-1PIGSTY~jammy_all.deb
| PIGSTY 1.1.0 u22.x86_64.pg17 : postgresql-17-fsm-core postgresql-17-fsm-core_1.1.0-1PIGSTY~jammy_all.deb
| PIGSTY 1.1.0 u22.x86_64.pg16 : postgresql-16-fsm-core postgresql-16-fsm-core_1.1.0-1PIGSTY~jammy_all.deb
| PIGSTY 1.1.0 u22.x86_64.pg15 : postgresql-15-fsm-core postgresql-15-fsm-core_1.1.0-1PIGSTY~jammy_all.deb
| PIGSTY MISS |
| u22.aarch64 | PIGSTY 1.1.0 u22.aarch64.pg18 : postgresql-18-fsm-core postgresql-18-fsm-core_1.1.0-1PIGSTY~jammy_all.deb
| PIGSTY 1.1.0 u22.aarch64.pg17 : postgresql-17-fsm-core postgresql-17-fsm-core_1.1.0-1PIGSTY~jammy_all.deb
| PIGSTY 1.1.0 u22.aarch64.pg16 : postgresql-16-fsm-core postgresql-16-fsm-core_1.1.0-1PIGSTY~jammy_all.deb
| PIGSTY 1.1.0 u22.aarch64.pg15 : postgresql-15-fsm-core postgresql-15-fsm-core_1.1.0-1PIGSTY~jammy_all.deb
| PIGSTY MISS |
| u24.x86_64 | PIGSTY 1.1.0 u24.x86_64.pg18 : postgresql-18-fsm-core postgresql-18-fsm-core_1.1.0-1PIGSTY~noble_all.deb
| PIGSTY 1.1.0 u24.x86_64.pg17 : postgresql-17-fsm-core postgresql-17-fsm-core_1.1.0-1PIGSTY~noble_all.deb
| PIGSTY 1.1.0 u24.x86_64.pg16 : postgresql-16-fsm-core postgresql-16-fsm-core_1.1.0-1PIGSTY~noble_all.deb
| PIGSTY 1.1.0 u24.x86_64.pg15 : postgresql-15-fsm-core postgresql-15-fsm-core_1.1.0-1PIGSTY~noble_all.deb
| PIGSTY MISS |
| u24.aarch64 | PIGSTY 1.1.0 u24.aarch64.pg18 : postgresql-18-fsm-core postgresql-18-fsm-core_1.1.0-1PIGSTY~noble_all.deb
| PIGSTY 1.1.0 u24.aarch64.pg17 : postgresql-17-fsm-core postgresql-17-fsm-core_1.1.0-1PIGSTY~noble_all.deb
| PIGSTY 1.1.0 u24.aarch64.pg16 : postgresql-16-fsm-core postgresql-16-fsm-core_1.1.0-1PIGSTY~noble_all.deb
| PIGSTY 1.1.0 u24.aarch64.pg15 : postgresql-15-fsm-core postgresql-15-fsm-core_1.1.0-1PIGSTY~noble_all.deb
| PIGSTY MISS |
| u26.x86_64 | PIGSTY 1.1.0 u26.x86_64.pg18 : postgresql-18-fsm-core postgresql-18-fsm-core_1.1.0-1PIGSTY~resolute_all.deb
| PIGSTY 1.1.0 u26.x86_64.pg17 : postgresql-17-fsm-core postgresql-17-fsm-core_1.1.0-1PIGSTY~resolute_all.deb
| PIGSTY 1.1.0 u26.x86_64.pg16 : postgresql-16-fsm-core postgresql-16-fsm-core_1.1.0-1PIGSTY~resolute_all.deb
| PIGSTY 1.1.0 u26.x86_64.pg15 : postgresql-15-fsm-core postgresql-15-fsm-core_1.1.0-1PIGSTY~resolute_all.deb
| PIGSTY MISS |
| u26.aarch64 | PIGSTY 1.1.0 u26.aarch64.pg18 : postgresql-18-fsm-core postgresql-18-fsm-core_1.1.0-1PIGSTY~resolute_all.deb
| PIGSTY 1.1.0 u26.aarch64.pg17 : postgresql-17-fsm-core postgresql-17-fsm-core_1.1.0-1PIGSTY~resolute_all.deb
| PIGSTY 1.1.0 u26.aarch64.pg16 : postgresql-16-fsm-core postgresql-16-fsm-core_1.1.0-1PIGSTY~resolute_all.deb
| PIGSTY 1.1.0 u26.aarch64.pg15 : postgresql-15-fsm-core postgresql-15-fsm-core_1.1.0-1PIGSTY~resolute_all.deb
| PIGSTY MISS |
Build
You can build the RPM / DEB packages for fsm_core using pig build:
pig build pkg fsm_core # build RPM / DEB packages
Install
You can install fsm_core directly. First, make sure the PGDG and PIGSTY repositories are added and enabled:
pig repo add pgsql -u # Add repo and update cache
Install the extension using pig or apt/yum/dnf:
pig install fsm_core; # Install for current active PG version
pig ext install -y fsm_core -v 18 # PG 18
pig ext install -y fsm_core -v 17 # PG 17
pig ext install -y fsm_core -v 16 # PG 16
pig ext install -y fsm_core -v 15 # PG 15
dnf install -y fsm_core_18 # PG 18
dnf install -y fsm_core_17 # PG 17
dnf install -y fsm_core_16 # PG 16
dnf install -y fsm_core_15 # PG 15
apt install -y postgresql-18-fsm-core # PG 18
apt install -y postgresql-17-fsm-core # PG 17
apt install -y postgresql-16-fsm-core # PG 16
apt install -y postgresql-15-fsm-core # PG 15
Create Extension:
CREATE EXTENSION fsm_core CASCADE; -- requires: ltree, pgmq, pg_jsonschema
Usage
Sources:
- fsm_core PGXN README
- PGXN control file
- 1.1.0 SQL definition
- Supabase 1.1.1-1.1.3 migrations
- worker execution ADR
- example definitions README
fsm_core is a finite-state-machine toolkit that stores FSM definitions, instances, transitions, dispatch queues, and event logs inside PostgreSQL. A machine definition is loaded from JSON, instances are created by name and version, and events are sent through SQL functions with optional pgmq queues or the newer scheduler dispatch path.
The PGXN packaged extension still declares default_version = '1.1.0' and requires PostgreSQL 15+, ltree, and pgmq. The repository’s packages/database-src project is at 1.1.3 and contains Supabase migration files through fsm_core--1.1.2--1.1.3.sql; the Rust/pgrx directory is explicitly marked not currently used. Treat the PGXN distribution as the packaged source and the Supabase migrations as main-branch material.
Core Tables and Types
fsm_core creates an enum fsm_state_type with atomic, compound, parallel, final, and history, plus tables including:
fsm_core.fsm_jsonfor loaded FSM definitions.fsm_core.fsm_statesfor expanded state nodes and ltree paths.fsm_core.fsm_transitionsfor transition rules.fsm_core.fsm_instancefor running instances.fsm_core.fsm_instance_lockfor advisory/concurrency state.fsm_core.fsm_instance_queue_event_logsandfsm_core.fsm_promise_queue_event_logsfor queued event history.fsm_core.fsm_dispatch_queueandfsm_core.fsm_daemon_nodein the main-branch scheduler path.
Load a Machine Definition
SELECT fsm_core.load_fsm_from_json_v2(
json_input := :'fsm_json'::jsonb,
root_node_text := 'root',
input_fsm_type := 'workflow',
input_fsm_name := 'creditCheck',
input_fsm_version := 'v01'
);
load_fsm_from_json_v2() validates JSON with fsm_core.fsm_json_schema(), caches the raw definition in fsm_json, then expands states and transitions. Upstream examples keep immutable version folders such as fsm/creditCheck/v01/xstate-fsm.json and fsm/creditCheck/v02/xstate-fsm.json; keep deployed versions immutable so existing instances continue against their original definition.
Create an Instance
SELECT fsm_core.create_fsm_instance_from_name_v2(
input_fsm_name := 'creditCheck',
input_fsm_version := 'v01',
input_fsm_context := '{"applicant_id":"a-42"}'::jsonb,
create_pgmq_queue := true
);
The PGXN 1.1.0 function checks that the named FSM exists, inserts an fsm_instance, copies transition authorization rows for that instance, and, when create_pgmq_queue is true, creates a pgmq queue named by the instance UUID and sends initialTransition_event.
The main-branch Supabase schema also has a scheduler-oriented path where instance creation can enqueue work through fsm_core.enqueue_fsm_dispatch_v2() instead of relying only on per-instance pgmq queues.
Send Events
SELECT fsm_core.send_event_to_fsm_queue_with_event_logs_v2(
input_fsm_instance_id := '00000000-0000-0000-0000-000000000000'::uuid,
input_fsm_instance_id_fsm_type := 'workflow',
input_fsm_instance_id_fsm_version := 'v01',
input_send_to_parent_queue_id := fsm_core.pg_system_queue_uuid(),
input_send_to_parent_queue_type := fsm_core.pg_system_queue_type(),
input_send_to_parent_queue_id_event_name := fsm_core.pg_system_event_name(),
input_event_name := 'APPROVE',
input_event_action_type := 'user',
input_event_data := '{"approved_by":"manager"}'::jsonb,
input_event_delay := 0
);
This helper writes to the instance queue with pgmq.send() and records the event in fsm_instance_queue_event_logs. For nested FSM and promise flows, send_event_to_queue_from_fsm_instance_id_v2() dispatches to the child-FSM or promise queue helper based on fsmtype.
Scheduler Dispatch Path
SELECT fsm_core.enqueue_fsm_dispatch_v2(
input_instance_id := '00000000-0000-0000-0000-000000000000'::uuid,
input_fsm_name := 'creditCheck',
input_fsm_version := 'v01',
input_dispatch_type := 'start'
);
SELECT fsm_core.schedule_next_pending();
The newer worker design uses fsm_dispatch_queue as the source of pending work and fsm_daemon_node as the registry of available fsmlet nodes. enqueue_fsm_dispatch_v2() inserts a pending dispatch row and emits pg_notify('fsm_scheduler_work', instance_id). schedule_next_pending() selects pending rows with FOR UPDATE SKIP LOCKED, chooses a daemon under its concurrency limit, marks the row scheduled, and notifies fsm_fsmlet_work_<daemon_id>.
This scheduler path appears in the main-branch Supabase schema and worker ADR, not in the PGXN 1.1.0 packaged SQL.
Resolve and Step State
SELECT fsm_core.resolve_state_value_v2(
input_json := '{"value":"pending"}'::jsonb,
input_fsm_name := 'creditCheck',
input_fsm_version := 'v01'
);
SELECT fsm_core.macrostep_v2(
event_name := 'APPROVE',
input_state_value := ARRAY['pending']::text[],
fsm_name_param := 'creditCheck',
fsm_version_param := 'v01'
);
The SQL surface also includes lower-level microstep_v2(), fsm_worker_v2(), lock helpers, archive helpers, and v1 compatibility functions. Prefer v2 entry points for new usage when both versions are present.
Dependency and Source Caveats
- Enable
ltreeandpgmqbeforefsm_core; account forpg_jsonschemabecause upstream Supabase setup and Pigsty package dependencies list it, even though the PGXN control file only declaresltree, pgmq. pgmqqueues andfsm_dispatch_queuerows are part of the async execution model, so queue names, retention, and scheduler cleanup should be operated like application data.- The upstream repo has no release tag for
1.1.0or1.1.3; the authoritative packaged source for PGXN ispackages/database-src/pgxn-dist. - The
packages/database-src-extensionRust/pgrx tree is exploratory and marked not currently used. Do not treat it as the active extension implementation. - Public docs are sparse compared with the SQL surface. Treat unlisted helper functions as internal unless the SQL definition, Supabase migration, or worker ADR demonstrates their role.
Feedback
Was this page helpful?
Thanks for the feedback! Please let us know how we can improve.
Sorry to hear that. Please let us know how we can improve.