@owlmeans/flow 0.1.18-rc.1 → 0.1.18-rc.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/flow/SKILL.md +95 -27
- package/package.json +6 -6
- package/build/.gitkeep +0 -0
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/flow",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-
|
|
4
|
+
"version": "0.1.18-rc.11",
|
|
5
|
+
"generatedAt": "2026-09-01T12:04:42.802Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -1,46 +1,114 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: flow
|
|
3
|
-
description: How to use @owlmeans/flow —
|
|
3
|
+
description: How to use @owlmeans/flow — a serializable step/transition state machine whose whole state collapses to one string. Auto-invoked when importing from this package, driving a multi-step workflow, or restoring one from a token.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
---
|
|
6
6
|
<!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
|
|
7
7
|
|
|
8
8
|
# @owlmeans/flow
|
|
9
9
|
|
|
10
|
-
**Layer:**
|
|
11
|
-
**Install:** `"@owlmeans/flow": "^0.1.18-rc.
|
|
10
|
+
**Layer:** Cross-cutting domain
|
|
11
|
+
**Install:** `"@owlmeans/flow": "^0.1.18-rc.11"` in `dependencies`
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
A flow is a set of named **steps**, each offering named **transitions** to other steps. What makes
|
|
14
|
+
it worth using over a hand-rolled switch is that the whole live state — flow, step, previous step,
|
|
15
|
+
entity, payload, message, ok — serializes to a single compact string and restores from it. That is
|
|
16
|
+
what lets a workflow survive a redirect, a page load, or a process.
|
|
17
|
+
|
|
18
|
+
## Key exports
|
|
14
19
|
|
|
15
20
|
| Export | Description |
|
|
16
|
-
|
|
17
|
-
| `
|
|
18
|
-
| `
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
| `
|
|
23
|
-
|
|
|
21
|
+
|---|---|
|
|
22
|
+
| `makeFlowModel(flow, provider?)` | Build a driver. `flow` is a `ShallowFlow` **object** (no provider needed) or a **string** — tried as a flow name first, then as a serialized token. |
|
|
23
|
+
| `FlowModel` | `target` `entity` `enter` `steps` `state` `setState` `payload` `updatePayload` `step` `transitions` `transition` `next` `transit` `serialize` |
|
|
24
|
+
| `ShallowFlow` / `FlowStep` / `FlowTransition` / `FlowState` / `FlowPayload` | The definition and state shapes |
|
|
25
|
+
| `FlowProvider` | `(flow: string) => Promise<Flow>` — resolves a flow by name |
|
|
26
|
+
| `flow(cfg, shallowFlow)` · `configureFlows(cfg, config)` | Register a flow as a config record / set `FlowConfig` |
|
|
27
|
+
| `stdStabFlow`, `stdAuthFlow` (deprecated), the OIDC/OIDP flows | Built-in flows |
|
|
28
|
+
| `FlowError`, `UnknownFlow`, `UnknownFlowStep`, `UnknownTransition`, … | The error family |
|
|
24
29
|
|
|
25
|
-
##
|
|
30
|
+
## Defining a flow
|
|
26
31
|
|
|
27
|
-
|
|
32
|
+
A definition is data, not a class. Each step carries an `index`, its own `step` name, the `service`
|
|
33
|
+
it belongs to, and a map of transitions keyed by transition name:
|
|
28
34
|
|
|
29
35
|
```typescript
|
|
30
|
-
import {
|
|
31
|
-
|
|
32
|
-
const onboardingFlow:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
welcome: {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
import type { ShallowFlow } from '@owlmeans/flow'
|
|
37
|
+
|
|
38
|
+
export const onboardingFlow: ShallowFlow = {
|
|
39
|
+
flow: 'onboarding',
|
|
40
|
+
initialStep: 'welcome',
|
|
41
|
+
steps: {
|
|
42
|
+
welcome: {
|
|
43
|
+
index: 0,
|
|
44
|
+
step: 'welcome',
|
|
45
|
+
service: 'onboarding',
|
|
46
|
+
initial: true,
|
|
47
|
+
transitions: {
|
|
48
|
+
next: { transition: 'next', step: 'profile' },
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
profile: {
|
|
52
|
+
index: 1,
|
|
53
|
+
step: 'profile',
|
|
54
|
+
service: 'onboarding',
|
|
55
|
+
transitions: {
|
|
56
|
+
next: { transition: 'next', step: 'done' },
|
|
57
|
+
back: { transition: 'back', step: 'welcome', explicit: true, reversible: true },
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
done: { index: 2, step: 'done', service: 'onboarding', transitions: {} },
|
|
61
|
+
},
|
|
40
62
|
}
|
|
41
63
|
```
|
|
42
64
|
|
|
43
|
-
##
|
|
65
|
+
## Driving it
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
const model = await makeFlowModel(onboardingFlow) // an object needs no provider
|
|
69
|
+
model.transit('next', true) // → 'profile'
|
|
70
|
+
const token = model.transit('next', true) // → 'done'; returns the SERIALIZED state
|
|
71
|
+
|
|
72
|
+
const restored = await makeFlowModel(token, provider) // a token DOES need a provider
|
|
73
|
+
restored.step().step // 'done'
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Rules
|
|
77
|
+
|
|
78
|
+
**`transit()` returns the serialized state, not the model.** It is the natural place to persist or
|
|
79
|
+
hand off from — a caller that ignores the return and calls `serialize()` afterwards gets the same
|
|
80
|
+
string, but the return is the signal that a transition is a checkpoint.
|
|
81
|
+
|
|
82
|
+
**A string argument is a flow name FIRST and a token second.** `makeFlowModel` asks the provider,
|
|
83
|
+
and only re-reads the string as a serialized token once the provider **throws**. A provider that
|
|
84
|
+
returns `null`/`undefined` for an unknown name therefore breaks every restore — it must throw
|
|
85
|
+
(`UnknownFlow` is what the built-ins raise).
|
|
86
|
+
|
|
87
|
+
**Passing a `ShallowFlow` object needs no provider at all.** That is the server-friendly path: a
|
|
88
|
+
runtime whose flows are code it declares itself needs no registry to start one, only to restore one.
|
|
89
|
+
|
|
90
|
+
**`next()` requires exactly one non-explicit outgoing transition.** It is what lets a driver advance
|
|
91
|
+
without knowing the vocabulary; mark every user-chosen or exceptional edge `explicit` so it can
|
|
92
|
+
never become the automatic answer.
|
|
93
|
+
|
|
94
|
+
**`FlowPayload` holds flat scalars only** — `string | number | boolean | null | undefined`. Anything
|
|
95
|
+
richer belongs in a record the payload points at. Payload is projected through the step's
|
|
96
|
+
`payloadMap` on serialization, so an unmapped key does not survive a round trip.
|
|
97
|
+
|
|
98
|
+
**`reversible` is what keeps `previous`**, and is what a "back" transition needs to return to where
|
|
99
|
+
it came from.
|
|
100
|
+
|
|
101
|
+
## Where it runs
|
|
102
|
+
|
|
103
|
+
Client drivers are `@owlmeans/client-flow` (`makeFlowService`) and `@owlmeans/web-flow`; they load
|
|
104
|
+
definitions from `FLOW_RECORD` config records through the config resource and carry the serialized
|
|
105
|
+
state in a query parameter (`FlowConfig.queryParam`).
|
|
106
|
+
|
|
107
|
+
There is **no server-side driver in this package**. A server or worker builds models directly from
|
|
108
|
+
`ShallowFlow` objects and supplies its own `FlowProvider` for restores — `@owlmeans/agent`'s
|
|
109
|
+
`makeStaticFlowProvider` is the reference implementation of one.
|
|
110
|
+
|
|
111
|
+
## Depends on
|
|
44
112
|
|
|
45
|
-
|
|
46
|
-
|
|
113
|
+
`@owlmeans/auth`, `@owlmeans/config`, `@owlmeans/error`, `@owlmeans/i18n`, `@owlmeans/resource`,
|
|
114
|
+
`@scure/base` (the token codec).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/flow",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.11",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
25
|
-
"@owlmeans/config": "^0.1.18-rc.
|
|
26
|
-
"@owlmeans/error": "^0.1.18-rc.
|
|
27
|
-
"@owlmeans/i18n": "^0.1.18-rc.
|
|
28
|
-
"@owlmeans/resource": "^0.1.18-rc.
|
|
24
|
+
"@owlmeans/auth": "^0.1.18-rc.7",
|
|
25
|
+
"@owlmeans/config": "^0.1.18-rc.8",
|
|
26
|
+
"@owlmeans/error": "^0.1.18-rc.6",
|
|
27
|
+
"@owlmeans/i18n": "^0.1.18-rc.6",
|
|
28
|
+
"@owlmeans/resource": "^0.1.18-rc.7",
|
|
29
29
|
"@scure/base": "^2.3.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
package/build/.gitkeep
DELETED
|
File without changes
|