Let me introduce to you the new 4th version of Krestianstvo SDK!
The main feature of the 4th version is the full-featured implementation of the Croquet Application Architecture in Functional Reactive Paradigm using SolidJS / S.JS and introduction of Recursive Portals. The only parts, that stayed the same as in the 3rd version of Krestianstvo SDK are: Reflector and Virtual Time. Their implementations are based on the Virtual World Framework, thus they were just slightly modified to suit Functional Reactive Paradigm.
The 4th version of Krestianstvo SDK is distributed as a standalone ESM module for JavaScript. It could be easily bundled with any Solid JS or Astro web application being hosted and running just in the Cloud.
The work on the 4th version was started in 2019, when I was working on Luminary and introduced the Functional Reactive Streams into the Croquet application architecture. The project with Rubik's Cube has shown, how Croquet gets a new look on Virtual Time and Promises inside actions, all backed by FRP. For example, the participants could delay the Virtual Time and observe their actions in virtual world in "slow motion".
Then in 2021 I participated in the first Festival for Web based Music. At the festival me and artist Delia Ramos were creating the web art project - "THIS IS NOT A CONCERT". In that project, an audience collaboratively explored the artwork inside virtual canvas space within multi-contextual / conceptual creative layers by touching the virtual objects, interacting or viewing through "filters" in Web Browser. The core object, that I needed to for that project was a Recursive Portal, that should work as a filter, portal to other virtual canvas spaces and also as a portal to itself.
But, comparable to the original Smalltalk version of the Croquet, as in the Virtual World Framework and in the 3rd version of Krestianstvo SDK there are still lack of Portals. The Croquet.io has introduced Portals for the Web, by using sandboxed HTML iFrames (Multiplane Portals for the Metaverse). And in Krestianstvo I wanted to implement Portals the same way as Croquet Smalltalk version does, as pure objects with an ability to make links to themselves, forming a Recursive Portals.
Finally, I was lucky to do it just in pure JavaScript, thanks to Solid JS! To make these all happen, it demanded of me to implement the Croquet application architecture nearly from scratch using functional reactive paradigm from Solid JS / S.JS.
The typical application in the 4th version of Krestianstvo SDK is an application, that will be build up from Solid JS main types of building blocks: Components and Reactive Primitives. Solid's fine-grained reactivity is built on three core primitives: Signals, Memos, and Effects. Together, they form an auto-tracking synchronization engine. Reactive computations take the form of function-wrapped expressions that execute synchronously (more in SolidJS documentation).
Krestianstvo uses Solid JS reactivity for implementing Croquet's concept of Model - View interconnection. Croquet Models - are just pure Solid JS Signals, Memos and Stores. Croquet Views - are just Solid JS lightweight Components with no state and no instances. All received external messages from Reflector and all internal Future messages, that responsible for actions are wrapped in a Signals and then dispatched by an Effects accordingly. For example, Smalltalk like "doesNotUnderstand" message is easily realised in Krestianstvo with Solid JS.
Here is an example of simple working app in Krestianstvo SDK | 4 (view it on codesandbox)
import { render } from "solid-js/web";
import { Selo, createLocalStore } from "krestianstvo";
const Counter = (props) => {
const [local, setLocal] = createLocalStore(
{
data: {
type: "Node",
nodeID: props.nodeID,
properties: {
name: props.nodeID,
count: 0,
ticking: false,
initialized: false
}
}
},
props
);
const inc = () => {
setLocal("data", "properties", "count", (c) => c + 1);
props.selo.future(props.nodeID, "inc", 1);
};
const initialize = () => {
inc();
};
props.selo.createAction(props.nodeID, "inc", inc);
props.selo.createAction(props.nodeID, "initialize", initialize);
return (
<>
<h1>{local.data.properties.count}</h1>
</>
);
};
render(
() => (
<Selo
nodeID={"counter"}
seloID={"sandbox_counter"}
component={Counter}
reflectorHost={"https://time.krestianstvo.org"}
/>
),
document.getElementById("root")
);
To be continued…
Demo playground: https://play.krestianstvo.org
Glitch demo project: https://krestianstvo-playground.glitch.me
The source code for Krestianstvo SDK 4: