@xmachines/play-solid 1.0.0-beta.18 → 1.0.0-beta.19
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/README.md +1 -1
- package/dist/PlayRenderer.js +15 -18
- package/dist/PlayRenderer.js.map +1 -1
- package/package.json +6 -7
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ Bridges TC39 Signal-driven actors to SolidJS's fine-grained reactivity. Business
|
|
|
13
13
|
- Routes action names from spec elements to `actor.send()` via the `actions` prop
|
|
14
14
|
- Manages per-view UI state in an `@xstate/store` atom (automatic or caller-supplied)
|
|
15
15
|
|
|
16
|
-
Per [
|
|
16
|
+
Per [Play RFC](../docs/rfc/play.md):
|
|
17
17
|
|
|
18
18
|
- **Actor Authority (INV-01):** Guards in the machine decide all state transitions
|
|
19
19
|
- **Passive Infrastructure (INV-04):** Solid observes signals and dispatches events — never decides
|
package/dist/PlayRenderer.js
CHANGED
|
@@ -3,29 +3,26 @@ import { createAtom as i } from "./node_modules/@xstate/store/dist/store-69e7e2d
|
|
|
3
3
|
import { xstateStoreStateStore as a } from "./node_modules/@json-render/xstate/dist/index.js";
|
|
4
4
|
import { ActorProvider as o } from "./useActor.js";
|
|
5
5
|
import { createComponent as s } from "solid-js/web";
|
|
6
|
-
import { createSignal as c, onCleanup as l
|
|
7
|
-
import { watchSignal as
|
|
6
|
+
import { createSignal as c, onCleanup as l } from "solid-js";
|
|
7
|
+
import { watchSignal as u } from "@xmachines/play-signals";
|
|
8
8
|
//#region src/PlayRenderer.tsx
|
|
9
|
-
var
|
|
10
|
-
let [
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
l(() => {
|
|
16
|
-
e();
|
|
17
|
-
});
|
|
9
|
+
var d = (d) => {
|
|
10
|
+
let [f, p] = c(d.actor.currentView.get()), m = null, h = null, g = u(d.actor.currentView, (e) => {
|
|
11
|
+
p(e);
|
|
12
|
+
});
|
|
13
|
+
return l(() => {
|
|
14
|
+
g();
|
|
18
15
|
}), s(o, {
|
|
19
16
|
get value() {
|
|
20
|
-
return
|
|
17
|
+
return d.actor;
|
|
21
18
|
},
|
|
22
19
|
get children() {
|
|
23
20
|
return (() => {
|
|
24
|
-
let o =
|
|
25
|
-
if (!o) return
|
|
21
|
+
let o = f();
|
|
22
|
+
if (!o) return d.fallback ?? null;
|
|
26
23
|
let c;
|
|
27
|
-
|
|
28
|
-
let l = Object.fromEntries(Object.entries(
|
|
24
|
+
d.store ? c = d.store : ((m === null || h !== o) && (m = a({ atom: i(o.spec.state ?? {}) }), h = o), c = m);
|
|
25
|
+
let l = Object.fromEntries(Object.entries(d.actions ?? {}).map(([e, t]) => [e, async (e = {}) => d.actor.send({
|
|
29
26
|
type: t,
|
|
30
27
|
...e
|
|
31
28
|
})]));
|
|
@@ -41,7 +38,7 @@ var f = (f) => {
|
|
|
41
38
|
return o.spec;
|
|
42
39
|
},
|
|
43
40
|
get registry() {
|
|
44
|
-
return
|
|
41
|
+
return d.registry;
|
|
45
42
|
}
|
|
46
43
|
});
|
|
47
44
|
} });
|
|
@@ -54,6 +51,6 @@ var f = (f) => {
|
|
|
54
51
|
});
|
|
55
52
|
};
|
|
56
53
|
//#endregion
|
|
57
|
-
export {
|
|
54
|
+
export { d as PlayRenderer };
|
|
58
55
|
|
|
59
56
|
//# sourceMappingURL=PlayRenderer.js.map
|
package/dist/PlayRenderer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlayRenderer.js","names":["createSignal","onCleanup","
|
|
1
|
+
{"version":3,"file":"PlayRenderer.js","names":["createSignal","onCleanup","Component","Renderer","StateProvider","ActionProvider","VisibilityProvider","ActionHandler","StateStore","createAtom","xstateStoreStateStore","watchSignal","PlayRendererProps","ViewMetadata","ActorProvider","PlayActor","PlayRenderer","props","view","setView","actor","currentView","get","internalStore","lastView","unwatch","nextView","_$createComponent","value","children","fallback","store","initialState","spec","state","Record","atom","handlers","Object","fromEntries","entries","actions","map","actionName","eventType","params","send","type","registry"],"sources":["../src/PlayRenderer.tsx"],"sourcesContent":["/**\n * PlayRenderer - Main SolidJS renderer component for XMachines Play architecture\n *\n * @packageDocumentation\n */\n\nimport { createSignal, onCleanup, type Component } from \"solid-js\";\nimport { Renderer, StateProvider, ActionProvider, VisibilityProvider } from \"@json-render/solid\";\nimport type { ActionHandler, StateStore } from \"@json-render/core\";\nimport { createAtom } from \"@xstate/store\";\nimport { xstateStoreStateStore } from \"@json-render/xstate\";\nimport { watchSignal } from \"@xmachines/play-signals\";\nimport type { PlayRendererProps } from \"./types.js\";\nimport type { ViewMetadata } from \"@xmachines/play-actor\";\nimport { ActorProvider, type PlayActor } from \"./useActor.js\";\n\n/**\n * Main renderer component that subscribes to actor signals and renders UI\n *\n * Architecture (per XMachines Play patterns):\n * - Subscribes to actor.currentView signal via TC39 Signal.subtle.Watcher\n * - Renders view.spec via @json-render/solid Renderer backed by the registry\n * - Routes actions to actor.send() via ActionProvider handlers\n * - SolidJS signal only for triggering renders, NOT business logic\n * - State store: uses external `store` prop if provided (controlled mode); otherwise\n * creates a fresh @xstate/store atom per view transition seeded from spec.state.\n *\n * Invariant: Actor Authority - Actor decides all state transitions via guards.\n * Invariant: Passive Infrastructure - Component observes signals and sends events.\n * Invariant: Signal-Only Reactivity - Business logic state lives in actor signals.\n *\n * @example\n * ```typescript\n * import { PlayRenderer } from \"@xmachines/play-solid\";\n * import { defineRegistry } from \"@json-render/solid\";\n *\n * const { registry } = defineRegistry(catalog, { components: { ... } });\n *\n * // Uncontrolled — fresh atom per view, seeded from spec.state:\n * <PlayRenderer actor={actor} registry={registry} actions={{ login: \"auth.login\" }} />\n *\n * // Controlled — caller provides and owns the store:\n * import { createAtom } from \"@xstate/store\";\n * import { xstateStoreStateStore } from \"@json-render/xstate\";\n * const store = xstateStoreStateStore({ atom: createAtom({ username: \"\" }) });\n * <PlayRenderer actor={actor} registry={registry} store={store} actions={{ login: \"auth.login\" }} />\n * ```\n */\nexport const PlayRenderer: Component<PlayRendererProps> = (props) => {\n\t// Create SolidJS signal for view\n\t// Signal is NOT business logic state - it's just SolidJS's render trigger\n\tconst [view, setView] = createSignal<ViewMetadata | null>(\n\t\tprops.actor.currentView.get() as ViewMetadata | null,\n\t);\n\n\t// Internal per-view store — recreated on each view transition when no external store.\n\tlet internalStore: StateStore | null = null;\n\tlet lastView: ViewMetadata | null = null;\n\n\t// Bridge TC39 Signal to SolidJS signal — subscribe synchronously during setup\n\t// (matching React/Vue behavior; onMount would defer until after DOM insertion,\n\t// silently dropping signal changes between createSignal and mount)\n\tconst unwatch = watchSignal(props.actor.currentView, (nextView: ViewMetadata | null) => {\n\t\tsetView(nextView);\n\t});\n\tonCleanup(() => {\n\t\tunwatch();\n\t});\n\n\treturn (\n\t\t<ActorProvider value={props.actor as PlayActor}>\n\t\t\t{(() => {\n\t\t\t\tconst currentView = view();\n\t\t\t\tif (!currentView) return props.fallback ?? null;\n\n\t\t\t\t// Resolve the store: external (controlled) or internal per-view atom\n\t\t\t\tlet store: StateStore;\n\t\t\t\tif (props.store) {\n\t\t\t\t\tstore = props.store;\n\t\t\t\t} else {\n\t\t\t\t\tif (internalStore === null || lastView !== currentView) {\n\t\t\t\t\t\tconst initialState =\n\t\t\t\t\t\t\t(currentView.spec.state as Record<string, unknown>) ?? {};\n\t\t\t\t\t\tinternalStore = xstateStoreStateStore({\n\t\t\t\t\t\t\tatom: createAtom(initialState),\n\t\t\t\t\t\t});\n\t\t\t\t\t\tlastView = currentView;\n\t\t\t\t\t}\n\t\t\t\t\tstore = internalStore;\n\t\t\t\t}\n\n\t\t\t\tconst handlers: Record<string, ActionHandler> = Object.fromEntries(\n\t\t\t\t\tObject.entries(props.actions ?? {}).map(([actionName, eventType]) => [\n\t\t\t\t\t\tactionName,\n\t\t\t\t\t\tasync (params: Record<string, unknown> = {}) =>\n\t\t\t\t\t\t\tprops.actor.send({ type: eventType, ...params }),\n\t\t\t\t\t]),\n\t\t\t\t);\n\n\t\t\t\treturn (\n\t\t\t\t\t<StateProvider store={store}>\n\t\t\t\t\t\t<ActionProvider handlers={handlers}>\n\t\t\t\t\t\t\t<VisibilityProvider>\n\t\t\t\t\t\t\t\t<Renderer spec={currentView.spec} registry={props.registry} />\n\t\t\t\t\t\t\t</VisibilityProvider>\n\t\t\t\t\t\t</ActionProvider>\n\t\t\t\t\t</StateProvider>\n\t\t\t\t);\n\t\t\t})()}\n\t\t</ActorProvider>\n\t);\n};\n"],"mappings":";;;;;;;;AAgDA,IAAagB,KAA8CC,MAAU;CAGpE,IAAM,CAACC,GAAMC,KAAWnB,EACvBiB,EAAMG,MAAMC,YAAYC,KAAK,CAC7B,EAGGC,IAAmC,MACnCC,IAAgC,MAK9BC,IAAUd,EAAYM,EAAMG,MAAMC,cAAcK,MAAkC;AACvFP,IAAQO,EAAS;GAChB;AAKF,QAJAzB,QAAgB;AACfwB,KAAS;GACR,EAEFE,EACEb,GAAa;EAAA,IAACc,QAAK;AAAA,UAAEX,EAAMG;;EAAkB,IAAAS,WAAA;AAAA,iBACrC;IACP,IAAMR,IAAcH,GAAM;AAC1B,QAAI,CAACG,EAAa,QAAOJ,EAAMa,YAAY;IAG3C,IAAIC;AACJ,IAAId,EAAMc,QACTA,IAAQd,EAAMc,UAEVR,MAAkB,QAAQC,MAAaH,OAG1CE,IAAgBb,EAAsB,EACrC0B,MAAM3B,EAFLY,EAAYY,KAAKC,SAAqC,EAAE,CAE5B,EAC7B,CAAC,EACFV,IAAWH,IAEZU,IAAQR;IAGT,IAAMc,IAA0CC,OAAOC,YACtDD,OAAOE,QAAQvB,EAAMwB,WAAW,EAAE,CAAC,CAACC,KAAK,CAACC,GAAYC,OAAe,CACpED,GACA,OAAOE,IAAkC,EAAE,KAC1C5B,EAAMG,MAAM0B,KAAK;KAAEC,MAAMH;KAAW,GAAGC;KAAQ,CAAC,CACjD,CACF,CAAC;AAED,WAAAlB,EACEvB,GAAa;KAAQ2B;KAAK,IAAAF,WAAA;AAAA,aAAAF,EACzBtB,GAAc;OAAWgC;OAAQ,IAAAR,WAAA;AAAA,eAAAF,EAChCrB,GAAkB,EAAA,IAAAuB,WAAA;AAAA,gBAAAF,EACjBxB,GAAQ;UAAA,IAAC8B,OAAI;AAAA,kBAAEZ,EAAYY;;UAAI,IAAEe,WAAQ;AAAA,kBAAE/B,EAAM+B;;UAAQ,CAAA;WAAA,CAAA;;OAAA,CAAA;;KAAA,CAAA;OAK3D;;EAAA,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xmachines/play-solid",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.19",
|
|
4
4
|
"description": "SolidJS renderer for XMachines Play architecture",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"catalog",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"type": "module",
|
|
21
21
|
"exports": {
|
|
22
22
|
".": {
|
|
23
|
+
"source": "./src/index.ts",
|
|
23
24
|
"types": "./dist/index.d.ts",
|
|
24
25
|
"default": "./dist/index.js"
|
|
25
26
|
}
|
|
@@ -29,17 +30,15 @@
|
|
|
29
30
|
},
|
|
30
31
|
"scripts": {
|
|
31
32
|
"build": "vite build && tsc --build",
|
|
32
|
-
"clean": "rm -rf dist
|
|
33
|
-
"typecheck": "tsc --noEmit",
|
|
34
|
-
"typecheck:test": "tsc --noEmit -p tsconfig.test.json",
|
|
33
|
+
"clean": "rm -rf dist *.tsbuildinfo coverage .vitest-attachments test/browser/__screenshots__",
|
|
35
34
|
"test": "vitest",
|
|
36
35
|
"test:watch": "vitest",
|
|
37
36
|
"test:ui": "vitest --ui",
|
|
38
37
|
"prepublishOnly": "npm run build"
|
|
39
38
|
},
|
|
40
39
|
"dependencies": {
|
|
41
|
-
"@xmachines/play-actor": "1.0.0-beta.
|
|
42
|
-
"@xmachines/play-signals": "1.0.0-beta.
|
|
40
|
+
"@xmachines/play-actor": "1.0.0-beta.19",
|
|
41
|
+
"@xmachines/play-signals": "1.0.0-beta.19"
|
|
43
42
|
},
|
|
44
43
|
"devDependencies": {
|
|
45
44
|
"@json-render/core": "^0.16.0",
|
|
@@ -48,7 +47,7 @@
|
|
|
48
47
|
"@solidjs/testing-library": "^0.8.10",
|
|
49
48
|
"@testing-library/jest-dom": "^6.9.1",
|
|
50
49
|
"@types/node": "^25.5.0",
|
|
51
|
-
"@xmachines/shared": "1.0.0-beta.
|
|
50
|
+
"@xmachines/shared": "1.0.0-beta.19",
|
|
52
51
|
"@xstate/store": ">=3.17.0",
|
|
53
52
|
"jsdom": "^29.0.1",
|
|
54
53
|
"solid-js": "^1.9.12",
|