@xmachines/play-view 0.0.0-bootstrap.0 → 4.0.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-store-lifecycle.js","sourceRoot":"","sources":["../src/view-store-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAKH,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACpF,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAoDnD;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CACvC,WAA0D;IAE1D,IAAI,aAAa,GAAsB,IAAI,CAAC;IAC5C,IAAI,WAAW,GAAuB,SAAS,CAAC;IAChD,IAAI,QAAQ,GAAoB,IAAI,CAAC;IACrC,IAAI,SAAS,GAAY,IAAI,CAAC;IAC9B,wEAAwE;IACxE,IAAI,aAAa,GAAsB,IAAI,CAAC;IAC5C,IAAI,YAAY,GAAsB,IAAI,CAAC;IAE3C,MAAM,KAAK,GAAG,GAAS,EAAE;QACxB,aAAa,GAAG,IAAI,CAAC;QACrB,WAAW,GAAG,SAAS,CAAC;QACxB,QAAQ,GAAG,IAAI,CAAC;QAChB,SAAS,GAAG,IAAI,CAAC;QACjB,aAAa,GAAG,IAAI,CAAC;QACrB,YAAY,GAAG,IAAI,CAAC;IACrB,CAAC,CAAC;IAEF,OAAO;QACN,KAAK;QACL,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO;YAC1C,iFAAiF;YACjF,IAAI,SAAS,KAAK,KAAK,EAAE,CAAC;gBACzB,MAAM,YAAY,GAAG,SAAS,KAAK,IAAI,IAAI,aAAa,KAAK,IAAI,CAAC;gBAClE,IAAI,CAAC,YAAY;oBAAE,KAAK,EAAE,CAAC;gBAC3B,SAAS,GAAG,KAAK,CAAC;YACnB,CAAC;YAED,IAAI,QAAoB,CAAC;YACzB,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,IAAI,aAAa,EAAE,CAAC;gBACnB,QAAQ,GAAG,aAAa,CAAC;gBACzB,IAAI,OAAO,EAAE,oBAAoB,KAAK,KAAK,EAAE,CAAC;oBAC7C,qBAAqB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;gBACvC,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;gBAC7B,IAAI,SAAS,GAAsB,aAAa,CAAC;gBACjD,IACC,SAAS,KAAK,IAAI;oBAClB,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,EACpE,CAAC;oBACF,SAAS,GAAG,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;oBACjD,aAAa,GAAG,SAAS,CAAC;oBAC1B,WAAW,GAAG,OAAO,CAAC;oBACtB,QAAQ,GAAG,IAAI,CAAC;gBACjB,CAAC;qBAAM,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBAClC,qBAAqB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;gBACxC,CAAC;gBACD,QAAQ,GAAG,IAAI,CAAC;gBAChB,QAAQ,GAAG,SAAS,CAAC;YACtB,CAAC;YAED,IAAI,aAAa,KAAK,QAAQ,EAAE,CAAC;gBAChC,aAAa,GAAG,QAAQ,CAAC;gBACzB,YAAY,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAC7C,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,YAA0B,EAAE,QAAQ,EAAE,CAAC;QAChF,CAAC;KACD,CAAC;AACH,CAAC"}
@@ -0,0 +1,168 @@
1
+ /**
2
+ * The view types that every renderer of the Play Architecture shares.
3
+ *
4
+ * `PlaySpec` is the spec that an actor publishes, `Viewable` is the capability that
5
+ * publishes it, and the two provider types are the framework-free half of the props and
6
+ * of the context value of a provider.
7
+ *
8
+ * They live here, and not with `PlayActor`, because each one names a type of
9
+ * `@xmachines/json-render-core`. An application that routes and renders no view
10
+ * therefore installs that package never.
11
+ *
12
+ * @packageDocumentation
13
+ */
14
+ import type { Signal } from "@xmachines/play-signals";
15
+ import type { PlayActor, ActorEvent } from "@xmachines/play-actor";
16
+ import type { Spec, StateStore, RenderErrorHandler, ActionHandler } from "@xmachines/json-render-core";
17
+ /**
18
+ * The XMachines extension of the `Spec` type of `@xmachines/json-render-core`.
19
+ *
20
+ * Each derived view receives the machine context in its state store, under the
21
+ * read-only `/context` subtree. A spec therefore reads the context through the
22
+ * ordinary `{ $state: "/context/…" }` grammar: in a prop, in a `visible` condition,
23
+ * and in `repeat.statePath`. The store always holds the complete context, and a
24
+ * spec reads only the paths that it needs.
25
+ */
26
+ export interface PlaySpec extends Spec {
27
+ /**
28
+ * The identity of the view of this derived spec. `deriveCurrentView` sets it from
29
+ * the meta entry that the derivation selected. A provider uses it as the key of its
30
+ * store lifecycle: a new `viewKey` seeds the store again, and the same `viewKey`
31
+ * refreshes `/context` in place, which keeps the ephemeral view state. Never write
32
+ * this field in `meta.view`.
33
+ */
34
+ readonly viewKey?: string;
35
+ }
36
+ /**
37
+ * The identity helper gives a view spec literal the type `PlaySpec` at the
38
+ * definition site. The compiler therefore checks the spec, and the IDE completes it.
39
+ *
40
+ * The XState `meta` field has the type `Record<string, unknown>`. TypeScript
41
+ * therefore infers no spec shape from the context. `typedSpec(...)` is the
42
+ * mechanism that starts the check where you write the spec. The parameter holds no
43
+ * `viewKey`: the derivation stamps that field, and it overwrites a value from an
44
+ * author without a notice. Therefore the compiler refuses a `viewKey` here.
45
+ *
46
+ * The check of an excess property works on an inline object literal only. For a
47
+ * spec in a variable, or for a spec from a spread, write `satisfies PlaySpec` at
48
+ * the literal instead.
49
+ *
50
+ * At run time this function does nothing: it returns the spec object without a
51
+ * change.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * meta: {
56
+ * view: typedSpec({
57
+ * root: "root",
58
+ * elements: {
59
+ * root: {
60
+ * type: "Dashboard",
61
+ * props: { username: { $state: "/context/username" } },
62
+ * children: [],
63
+ * },
64
+ * },
65
+ * }),
66
+ * }
67
+ * ```
68
+ */
69
+ export declare function typedSpec(spec: Omit<PlaySpec, "viewKey">): PlaySpec;
70
+ /**
71
+ * The actor capability that exposes a renderable view state.
72
+ *
73
+ * `Viewable` marks an actor that publishes a `currentView` signal.
74
+ * A renderer, such as `PlayRenderer`, reads this contract. It converts the
75
+ * description of the current view into a concrete UI, and the framework adapter
76
+ * therefore holds no view logic.
77
+ */
78
+ export interface Viewable {
79
+ /**
80
+ * The signal of the current view. It holds the json-render PlaySpec of the current
81
+ * machine state, or null when no view is active.
82
+ *
83
+ * The infrastructure renders the view. This is the Logic-Driven UI invariant.
84
+ */
85
+ readonly currentView: Signal.State<PlaySpec | null>;
86
+ }
87
+ /**
88
+ * The framework-agnostic base of the `ViewContextValue` type in each framework.
89
+ *
90
+ * It holds the three fields that are identical in React, Vue, Solid, and Svelte.
91
+ * The `registry` field belongs to one framework, because each framework has its own
92
+ * `ComponentRegistry` type. Therefore `TRegistry` gives its type, and this is the
93
+ * same generic parameter as in `BaseActorProviderProps`.
94
+ *
95
+ * @typeParam TRegistry - The registry type of the component of the framework, for example `ComponentRegistry` from `@xmachines/json-render-react`.
96
+ */
97
+ export interface BaseViewContextValue<TRegistry extends object> {
98
+ /** The current PlaySpec to render. */
99
+ spec: PlaySpec;
100
+ /** The action handlers, resolved against the live StateStore. */
101
+ handlers: Record<string, ActionHandler>;
102
+ /** The component registry, from registryResult.registry. */
103
+ registry: TRegistry;
104
+ /**
105
+ * The active StateStore. Give it to JSONUIProvider or JsonUIProvider as `store`, and the providers then share the state.
106
+ */
107
+ store: StateStore;
108
+ }
109
+ /**
110
+ * The actor that a view provider reads: the contract, and the view capability.
111
+ *
112
+ * It names NO engine. A provider reads `currentView` and `send`, and nothing else — the
113
+ * measurement is 20 reads of `currentView` and 16 of `send` across the five renderers, and
114
+ * no read of any other member. The type said `ViewActor`
115
+ * before, which named XState in every renderer AND erased the snapshot and the event union
116
+ * of the machine at the same time.
117
+ *
118
+ * It does NOT name `Routable`. The view implies no routing.
119
+ *
120
+ * @typeParam TSnapshot - The snapshot type that `state` holds.
121
+ * @typeParam TEvent - The event union that `send` accepts.
122
+ */
123
+ export type ViewActor<TSnapshot = unknown, TEvent extends ActorEvent = ActorEvent> = PlayActor<TSnapshot, TEvent> & Viewable;
124
+ /**
125
+ * The framework-agnostic base props. Every `ActorProvider` implementation shares
126
+ * them: React, Vue, Solid, and Svelte. `TRegistry` holds the
127
+ * `DefineRegistryResult` type of the framework. `RenderErrorHandler` comes from
128
+ * `@xmachines/json-render-core`, and a second generic parameter is therefore not
129
+ * necessary.
130
+ *
131
+ * Each framework package extends this interface with its `fallback` field, its
132
+ * `onError` field, and its `children` field.
133
+ *
134
+ * @typeParam TRegistry - The `DefineRegistryResult` type of the framework.
135
+ *
136
+ * @example
137
+ * ```ts
138
+ * import type { BaseActorProviderProps , ViewActor} from "@xmachines/play-view";
139
+ * import type { DefineRegistryResult } from "@xmachines/json-render-react";
140
+ *
141
+ * interface ActorProviderProps extends BaseActorProviderProps<DefineRegistryResult> {
142
+ * fallback?: React.ReactNode;
143
+ * children: React.ReactNode;
144
+ * }
145
+ * ```
146
+ */
147
+ export interface BaseActorProviderProps<TRegistry extends {
148
+ registry: object;
149
+ handlers: (...args: never[]) => unknown;
150
+ }, TActor extends ViewActor = ViewActor> {
151
+ /** The actor instance with the currentView signal. It requires the Viewable capability. */
152
+ actor: TActor;
153
+ /** The complete result of defineRegistry(). It holds the component registry and the factory of the action handlers. */
154
+ registryResult: TRegistry;
155
+ /**
156
+ * The optional external StateStore, which is the controlled mode.
157
+ * With this option, the provider ignores spec.state, and this store is the single
158
+ * source of truth. Without it, the provider makes a new @xstate/store atom for each
159
+ * view transition, with the values of spec.state.
160
+ */
161
+ store?: StateStore;
162
+ /**
163
+ * The provider calls it when one catalog component throws during a render.
164
+ * This handler replaces every onRenderError of defineRegistry.
165
+ */
166
+ onRenderError?: RenderErrorHandler;
167
+ }
168
+ //# sourceMappingURL=view-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-types.d.ts","sourceRoot":"","sources":["../src/view-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EACX,IAAI,EACJ,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,MAAM,6BAA6B,CAAC;AAErC;;;;;;;;GAQG;AACH,MAAM,WAAW,QAAS,SAAQ,IAAI;IACrC;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,QAAQ,CAEnE;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;CACpD;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAoB,CAAC,SAAS,SAAS,MAAM;IAC7D,sCAAsC;IACtC,IAAI,EAAE,QAAQ,CAAC;IACf,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxC,4DAA4D;IAC5D,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,KAAK,EAAE,UAAU,CAAC;CAClB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,SAAS,CAAC,SAAS,GAAG,OAAO,EAAE,MAAM,SAAS,UAAU,GAAG,UAAU,IAAI,SAAS,CAC7F,SAAS,EACT,MAAM,CACN,GACA,QAAQ,CAAC;AAEV;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,sBAAsB,CACtC,SAAS,SAAS;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAA;CAAE,EAC/E,MAAM,SAAS,SAAS,GAAG,SAAS;IAEpC,2FAA2F;IAC3F,KAAK,EAAE,MAAM,CAAC;IACd,uHAAuH;IACvH,cAAc,EAAE,SAAS,CAAC;IAC1B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB;;;OAGG;IACH,aAAa,CAAC,EAAE,kBAAkB,CAAC;CACnC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * The identity helper gives a view spec literal the type `PlaySpec` at the
3
+ * definition site. The compiler therefore checks the spec, and the IDE completes it.
4
+ *
5
+ * The XState `meta` field has the type `Record<string, unknown>`. TypeScript
6
+ * therefore infers no spec shape from the context. `typedSpec(...)` is the
7
+ * mechanism that starts the check where you write the spec. The parameter holds no
8
+ * `viewKey`: the derivation stamps that field, and it overwrites a value from an
9
+ * author without a notice. Therefore the compiler refuses a `viewKey` here.
10
+ *
11
+ * The check of an excess property works on an inline object literal only. For a
12
+ * spec in a variable, or for a spec from a spread, write `satisfies PlaySpec` at
13
+ * the literal instead.
14
+ *
15
+ * At run time this function does nothing: it returns the spec object without a
16
+ * change.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * meta: {
21
+ * view: typedSpec({
22
+ * root: "root",
23
+ * elements: {
24
+ * root: {
25
+ * type: "Dashboard",
26
+ * props: { username: { $state: "/context/username" } },
27
+ * children: [],
28
+ * },
29
+ * },
30
+ * }),
31
+ * }
32
+ * ```
33
+ */
34
+ export function typedSpec(spec) {
35
+ return spec;
36
+ }
37
+ //# sourceMappingURL=view-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-types.js","sourceRoot":"","sources":["../src/view-types.ts"],"names":[],"mappings":"AA0CA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,UAAU,SAAS,CAAC,IAA+B;IACxD,OAAO,IAAI,CAAC;AACb,CAAC"}
package/package.json CHANGED
@@ -1,16 +1,77 @@
1
1
  {
2
- "name": "@xmachines/play-view",
3
- "version": "0.0.0-bootstrap.0",
4
- "description": "Placeholder. This version contains no code. The first release of @xmachines/play-view is 4.0.0.",
5
- "license": "MIT",
6
- "author": "XMachines",
7
- "repository": {
8
- "type": "git",
9
- "url": "git+https://gitlab.com/xmachin-es/xmachines-js.git",
10
- "directory": "packages/play-view"
11
- },
12
- "files": [
13
- "README.md",
14
- "LICENSE"
15
- ]
2
+ "name": "@xmachines/play-view",
3
+ "version": "4.0.0",
4
+ "private": false,
5
+ "description": "The shared view half of every XMachines renderer: the view store lifecycle, the context projection, and the provider guards",
6
+ "keywords": [
7
+ "json-render",
8
+ "play-architecture",
9
+ "view",
10
+ "xmachines",
11
+ "xstate"
12
+ ],
13
+ "license": "MIT",
14
+ "author": "XMachines Contributors",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://gitlab.com/xmachin-es/xmachines-js.git",
18
+ "directory": "packages/play-view"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "README.md",
23
+ "LICENSE"
24
+ ],
25
+ "type": "module",
26
+ "sideEffects": false,
27
+ "main": "./dist/index.js",
28
+ "types": "./dist/index.d.ts",
29
+ "exports": {
30
+ ".": {
31
+ "types": "./dist/index.d.ts",
32
+ "default": "./dist/index.js"
33
+ },
34
+ "./errors": {
35
+ "types": "./dist/errors.d.ts",
36
+ "default": "./dist/errors.js"
37
+ },
38
+ "./package.json": "./package.json"
39
+ },
40
+ "publishConfig": {
41
+ "access": "public"
42
+ },
43
+ "scripts": {
44
+ "build": "vite build && tsc --build",
45
+ "clean": "rm -rf dist *.tsbuildinfo coverage node_modules/.svelte2tsx-* node_modules/.vite*",
46
+ "test": "vitest",
47
+ "test:coverage": "vitest run --coverage",
48
+ "lint": "oxlint .",
49
+ "lint:security": "node ../../scripts/semgrep-scan.mjs",
50
+ "lint:fix": "oxlint --fix .",
51
+ "format": "oxfmt .",
52
+ "format:check": "oxfmt --check ."
53
+ },
54
+ "dependencies": {
55
+ "@xmachines/play-actor": "4.0.0"
56
+ },
57
+ "devDependencies": {
58
+ "@testing-library/jest-dom": "^7.0.1",
59
+ "@types/node": "^26.6.2",
60
+ "@xmachines/json-render-core": "^0.20.0-xm.4",
61
+ "@xmachines/play": "4.0.0",
62
+ "@xmachines/play-signals": "4.0.0",
63
+ "oxfmt": "^0.68.0",
64
+ "oxlint": "^1.83.0",
65
+ "vite": "^8.3.0",
66
+ "vitest": "^5.0.1",
67
+ "xstate": "^5.33.0"
68
+ },
69
+ "peerDependencies": {
70
+ "@xmachines/json-render-core": "^0.20.0-xm.4",
71
+ "@xmachines/play": "4.0.0",
72
+ "@xmachines/play-signals": "4.0.0"
73
+ },
74
+ "engines": {
75
+ "node": ">=24.0.0"
76
+ }
16
77
  }