Working with Contexts
Cross.stream uses contexts to partition event streams. Every frame belongs to a context, with the system context being the default where operations happen if no specific context is specified.
System Context
When you first start using cross.stream, you’re working in the system context. Let’s see this in action:
.cat
─#─┬──topic───┬────────────id─────────────┬─hash─┬─meta─┬───ttl───0 │ xs.start │ 03d4q1o70y6ek0ig8hwy9q00n │ │ │───┴──────────┴───────────────────────────┴──────┴──────┴─────────
The xs.start
frame above is in the system context. Let’s add a note:
"system note" | .append notes
───────┬─────────────────────────────────────────────────────topic │ notesid │ 03d4q1qhbiv09ovtuhokw5yxvhash │ sha256-wIcRiyKpOjA1Z8O+wZvoiMXYgGEzPQOhlA8AOptOhBY=meta │ttl │ forever───────┴─────────────────────────────────────────────────────
xs cat ./store
{"topic":"xs.start","id":"03d4qiab9g5vagrlrvxa2vjw0","hash":null,"meta":null,"ttl":null}
The xs.start
frame above is in the system context. Let’s add a note:
echo "system note" | xs append ./store notes
{"topic":"notes","id":"03d4qic9vqkve1krajjtlbavd","hash":"sha256-24yYvzQ4Zd3Go/WevV9ol+KzkdTgQvlyNN2NVSGMjFE=","meta":null,"ttl":"forever"}
Creating a New Context
To create a new context, we use the special xs.context
topic:
"my project" | .append xs.context
───────┬─────────────────────────────────────────────────────topic │ xs.contextid │ 03d4qbrxizqgav09m7hicksb0meta │ttl │ forever───────┴─────────────────────────────────────────────────────# Save the context ID for later use> let project_context = (ls | last).id
echo "my project" | xs append ./store xs.context
{"topic":"xs.context","id":"03d4qbrxizqgav09m7hicksb0","meta":null,"ttl":"forever"}# Save the context ID for later usePROJECT_CONTEXT=03d4qbrxizqgav09m7hicksb0
Using Contexts
Now we can add frames to our new context:
"project note" | .append notes -c $project_context.cat -c $project_context
─#─┬──topic───┬────────────id─────────────┬────────────────────────hash─────────────────────────┬─meta─┬───ttl───0 │ notes │ 03d4qbrxizqgav09m7hicksb0 │ sha256-KDyb7pypM+8aLiq5obfpCqbMmb6LvvPnCu2+y9eWd0c= │ │ forever───┴──────────┴───────────────────────────┴─────────────────────────────────────────────────────┴──────┴─────────
Notice how .cat -c $project_context
only shows frames from our project
context. The system note we created earlier isn’t visible.
The head
command is also context-aware:
.head notes -c $project_context | .cas
project note
echo "project note" | xs append ./store notes -c $PROJECT_CONTEXTxs cat ./store -c $PROJECT_CONTEXT
{"topic":"notes","id":"03d4qbrxizqgav09m7hicksb0","hash":"sha256-KDyb7pypM+8aLiq5obfpCqbMmb6LvvPnCu2+y9eWd0c=","meta":null,"ttl":"forever"}
Notice how xs cat -c $PROJECT_CONTEXT
only shows frames from our project
context. The system note we created earlier isn’t visible.
The head
command is also context-aware:
xs head ./store notes -c $PROJECT_CONTEXT | jq -r .hash | xargs xs cas ./store
project note
Setting a Default Context
Instead of specifying the context with each command, you can set a default:
$env.XS_CONTEXT = $project_context"another project note" | .append notes # Uses project context automatically.cat # Also uses project context
export XS_CONTEXT=$PROJECT_CONTEXTecho "another project note" | xs append ./store notes # Uses project context automaticallyxs cat ./store # Also uses project context
Viewing All Contexts
Sometimes you may want to see frames across all contexts:
.cat --all
─#─┬──topic───┬────────────id─────────────┬────────────────────────hash─────────────────────────┬─meta─┬───ttl───0 │ xs.start │ 03d4q1o70y6ek0ig8hwy9q00n │ │ │1 │ notes │ 03d4q1qhbiv09ovtuhokw5yxv │ sha256-wIcRiyKpOjA1Z8O+wZvoiMXYgGEzPQOhlA8AOptOhBY= │ │ forever2 │ xs.context│ 03d4qbrxizqgav09m7hicksb0 │ sha256-KDyb7pypM+8aLiq5obfpCqbMmb6LvvPnCu2+y9eWd0c= │ │ forever3 │ notes │ 03d4qkzpbiv09ovtuhokw5yxv │ sha256-LMcRiyKpOjA1Z8O+wZvoiMXYgGEzPQOhlA8AOptOhBY= │ │ forever───┴──────────┴───────────────────────────┴─────────────────────────────────────────────────────┴──────┴─────────
xs cat ./store --all
{"topic":"xs.start","id":"03d4q1o70y6ek0ig8hwy9q00n","hash":null,"meta":null,"ttl":null}{"topic":"notes","id":"03d4q1qhbiv09ovtuhokw5yxv","hash":"sha256-wIcRiyKpOjA1Z8O+wZvoiMXYgGEzPQOhlA8AOptOhBY=","meta":null,"ttl":"forever"}{"topic":"xs.context","id":"03d4qbrxizqgav09m7hicksb0","hash":"sha256-KDyb7pypM+8aLiq5obfpCqbMmb6LvvPnCu2+y9eWd0c=","meta":null,"ttl":"forever"}{"topic":"notes","id":"03d4qkzpbiv09ovtuhokw5yxv","hash":"sha256-LMcRiyKpOjA1Z8O+wZvoiMXYgGEzPQOhlA8AOptOhBY=","meta":null,"ttl":"forever"}
Managing Contexts with .ctx Commands
When using the NuShell convenience module (xs.nu
), you get access to
additional context management commands under the .ctx
namespace. These provide
a more interactive way to work with contexts.
Listing Contexts
View all available contexts and see which one is active:
.ctx list
─#─┬───────────────id───────────────┬─active─┐0 │ 0000000000000000000000000 │ true │1 │ 03d4qbrxizqgav09m7hicksb0 │ false │───┴──────────────────────────────────┴────────┘
Switching Contexts
Change your active context:
.ctx switch 03d4qbrxizqgav09m7hicksb0
03d4qbrxizqgav09m7hicksb0
You can also switch interactively:
.ctx switch
# (shows interactive list to select from)03d4qbrxizqgav09m7hicksb0
Creating a New Context
Create and automatically switch to a new context:
.ctx new
03d4qbrxizqgav09m7hicksb0
Viewing Current Context
Check your current context:
.ctx
03d4qbrxizqgav09m7hicksb0