@cohesivesystems/presentation-react 0.1.0-alpha.1

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.
Files changed (252) hide show
  1. package/LICENSE +55 -0
  2. package/dist/collection-chrome-slot-renderer-registry.d.ts +12 -0
  3. package/dist/collection-chrome-slot-renderer-registry.d.ts.map +1 -0
  4. package/dist/collection-chrome-slot-renderer-registry.js +12 -0
  5. package/dist/collection-chrome-slot-renderer-registry.js.map +1 -0
  6. package/dist/collection-selection-state-context.d.ts +6 -0
  7. package/dist/collection-selection-state-context.d.ts.map +1 -0
  8. package/dist/collection-selection-state-context.js +25 -0
  9. package/dist/collection-selection-state-context.js.map +1 -0
  10. package/dist/collection-selection-state.d.ts +3 -0
  11. package/dist/collection-selection-state.d.ts.map +1 -0
  12. package/dist/collection-selection-state.js +52 -0
  13. package/dist/collection-selection-state.js.map +1 -0
  14. package/dist/document-workspace-runtime.d.ts +262 -0
  15. package/dist/document-workspace-runtime.d.ts.map +1 -0
  16. package/dist/document-workspace-runtime.js +699 -0
  17. package/dist/document-workspace-runtime.js.map +1 -0
  18. package/dist/index.d.ts +51 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +51 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/input-form-endpoint-runtime.d.ts +140 -0
  23. package/dist/input-form-endpoint-runtime.d.ts.map +1 -0
  24. package/dist/input-form-endpoint-runtime.js +280 -0
  25. package/dist/input-form-endpoint-runtime.js.map +1 -0
  26. package/dist/local-flow-state-data-source-projection.d.ts +21 -0
  27. package/dist/local-flow-state-data-source-projection.d.ts.map +1 -0
  28. package/dist/local-flow-state-data-source-projection.js +65 -0
  29. package/dist/local-flow-state-data-source-projection.js.map +1 -0
  30. package/dist/navigation-runtime-context.d.ts +22 -0
  31. package/dist/navigation-runtime-context.d.ts.map +1 -0
  32. package/dist/navigation-runtime-context.js +23 -0
  33. package/dist/navigation-runtime-context.js.map +1 -0
  34. package/dist/navigation-shell-frame-renderer-registry.d.ts +20 -0
  35. package/dist/navigation-shell-frame-renderer-registry.d.ts.map +1 -0
  36. package/dist/navigation-shell-frame-renderer-registry.js +9 -0
  37. package/dist/navigation-shell-frame-renderer-registry.js.map +1 -0
  38. package/dist/navigation-shell-region-component-registry.d.ts +50 -0
  39. package/dist/navigation-shell-region-component-registry.d.ts.map +1 -0
  40. package/dist/navigation-shell-region-component-registry.js +44 -0
  41. package/dist/navigation-shell-region-component-registry.js.map +1 -0
  42. package/dist/navigation-shell-slot-renderer-registry.d.ts +22 -0
  43. package/dist/navigation-shell-slot-renderer-registry.d.ts.map +1 -0
  44. package/dist/navigation-shell-slot-renderer-registry.js +9 -0
  45. package/dist/navigation-shell-slot-renderer-registry.js.map +1 -0
  46. package/dist/page-host-projection.d.ts +127 -0
  47. package/dist/page-host-projection.d.ts.map +1 -0
  48. package/dist/page-host-projection.js +59 -0
  49. package/dist/page-host-projection.js.map +1 -0
  50. package/dist/page-host-renderer-registry.d.ts +72 -0
  51. package/dist/page-host-renderer-registry.d.ts.map +1 -0
  52. package/dist/page-host-renderer-registry.js +63 -0
  53. package/dist/page-host-renderer-registry.js.map +1 -0
  54. package/dist/presentation-action-group-runtime-options.d.ts +36 -0
  55. package/dist/presentation-action-group-runtime-options.d.ts.map +1 -0
  56. package/dist/presentation-action-group-runtime-options.js +50 -0
  57. package/dist/presentation-action-group-runtime-options.js.map +1 -0
  58. package/dist/presentation-action-runtime.d.ts +52 -0
  59. package/dist/presentation-action-runtime.d.ts.map +1 -0
  60. package/dist/presentation-action-runtime.js +78 -0
  61. package/dist/presentation-action-runtime.js.map +1 -0
  62. package/dist/presentation-data-source-binding-runtime.d.ts +3 -0
  63. package/dist/presentation-data-source-binding-runtime.d.ts.map +1 -0
  64. package/dist/presentation-data-source-binding-runtime.js +65 -0
  65. package/dist/presentation-data-source-binding-runtime.js.map +1 -0
  66. package/dist/presentation-data-source-binding.d.ts +12 -0
  67. package/dist/presentation-data-source-binding.d.ts.map +1 -0
  68. package/dist/presentation-data-source-binding.js +13 -0
  69. package/dist/presentation-data-source-binding.js.map +1 -0
  70. package/dist/presentation-flow-runtime.d.ts +139 -0
  71. package/dist/presentation-flow-runtime.d.ts.map +1 -0
  72. package/dist/presentation-flow-runtime.js +514 -0
  73. package/dist/presentation-flow-runtime.js.map +1 -0
  74. package/dist/presentation-module-context.d.ts +4 -0
  75. package/dist/presentation-module-context.d.ts.map +1 -0
  76. package/dist/presentation-module-context.js +6 -0
  77. package/dist/presentation-module-context.js.map +1 -0
  78. package/dist/presentation-module-provider.d.ts +7 -0
  79. package/dist/presentation-module-provider.d.ts.map +1 -0
  80. package/dist/presentation-module-provider.js +7 -0
  81. package/dist/presentation-module-provider.js.map +1 -0
  82. package/dist/presentation-projection-diagnostics-context.d.ts +8 -0
  83. package/dist/presentation-projection-diagnostics-context.d.ts.map +1 -0
  84. package/dist/presentation-projection-diagnostics-context.js +3 -0
  85. package/dist/presentation-projection-diagnostics-context.js.map +1 -0
  86. package/dist/presentation-projection-diagnostics-hooks.d.ts +4 -0
  87. package/dist/presentation-projection-diagnostics-hooks.d.ts.map +1 -0
  88. package/dist/presentation-projection-diagnostics-hooks.js +17 -0
  89. package/dist/presentation-projection-diagnostics-hooks.js.map +1 -0
  90. package/dist/presentation-projection-diagnostics-runtime.d.ts +12 -0
  91. package/dist/presentation-projection-diagnostics-runtime.d.ts.map +1 -0
  92. package/dist/presentation-projection-diagnostics-runtime.js +54 -0
  93. package/dist/presentation-projection-diagnostics-runtime.js.map +1 -0
  94. package/dist/presentation-projection-trace.d.ts +27 -0
  95. package/dist/presentation-projection-trace.d.ts.map +1 -0
  96. package/dist/presentation-projection-trace.js +54 -0
  97. package/dist/presentation-projection-trace.js.map +1 -0
  98. package/dist/presentation-query-form-runtime.d.ts +30 -0
  99. package/dist/presentation-query-form-runtime.d.ts.map +1 -0
  100. package/dist/presentation-query-form-runtime.js +75 -0
  101. package/dist/presentation-query-form-runtime.js.map +1 -0
  102. package/dist/presentation-query-form-state-adapter-registry.d.ts +4 -0
  103. package/dist/presentation-query-form-state-adapter-registry.d.ts.map +1 -0
  104. package/dist/presentation-query-form-state-adapter-registry.js +13 -0
  105. package/dist/presentation-query-form-state-adapter-registry.js.map +1 -0
  106. package/dist/presentation-query-form-state-context.d.ts +20 -0
  107. package/dist/presentation-query-form-state-context.d.ts.map +1 -0
  108. package/dist/presentation-query-form-state-context.js +20 -0
  109. package/dist/presentation-query-form-state-context.js.map +1 -0
  110. package/dist/presentation-query-form-state.d.ts +29 -0
  111. package/dist/presentation-query-form-state.d.ts.map +1 -0
  112. package/dist/presentation-query-form-state.js +99 -0
  113. package/dist/presentation-query-form-state.js.map +1 -0
  114. package/dist/presentation-renderer-registry.d.ts +109 -0
  115. package/dist/presentation-renderer-registry.d.ts.map +1 -0
  116. package/dist/presentation-renderer-registry.js +25 -0
  117. package/dist/presentation-renderer-registry.js.map +1 -0
  118. package/dist/presentation-standards-context.d.ts +4 -0
  119. package/dist/presentation-standards-context.d.ts.map +1 -0
  120. package/dist/presentation-standards-context.js +12 -0
  121. package/dist/presentation-standards-context.js.map +1 -0
  122. package/dist/presentation-standards-provider.d.ts +14 -0
  123. package/dist/presentation-standards-provider.d.ts.map +1 -0
  124. package/dist/presentation-standards-provider.js +16 -0
  125. package/dist/presentation-standards-provider.js.map +1 -0
  126. package/dist/projected-document-action-runtime-bindings.d.ts +20 -0
  127. package/dist/projected-document-action-runtime-bindings.d.ts.map +1 -0
  128. package/dist/projected-document-action-runtime-bindings.js +88 -0
  129. package/dist/projected-document-action-runtime-bindings.js.map +1 -0
  130. package/dist/projected-document-action-runtime.d.ts +76 -0
  131. package/dist/projected-document-action-runtime.d.ts.map +1 -0
  132. package/dist/projected-document-action-runtime.js +224 -0
  133. package/dist/projected-document-action-runtime.js.map +1 -0
  134. package/dist/projected-document-process-preview-action-runtime-bindings.d.ts +26 -0
  135. package/dist/projected-document-process-preview-action-runtime-bindings.d.ts.map +1 -0
  136. package/dist/projected-document-process-preview-action-runtime-bindings.js +106 -0
  137. package/dist/projected-document-process-preview-action-runtime-bindings.js.map +1 -0
  138. package/dist/projected-document-process-preview-action-runtime.d.ts +321 -0
  139. package/dist/projected-document-process-preview-action-runtime.d.ts.map +1 -0
  140. package/dist/projected-document-process-preview-action-runtime.js +729 -0
  141. package/dist/projected-document-process-preview-action-runtime.js.map +1 -0
  142. package/dist/projected-document-process-preview-capability-runtime.d.ts +47 -0
  143. package/dist/projected-document-process-preview-capability-runtime.d.ts.map +1 -0
  144. package/dist/projected-document-process-preview-capability-runtime.js +49 -0
  145. package/dist/projected-document-process-preview-capability-runtime.js.map +1 -0
  146. package/dist/projected-document-workspace-action-runtime.d.ts +87 -0
  147. package/dist/projected-document-workspace-action-runtime.d.ts.map +1 -0
  148. package/dist/projected-document-workspace-action-runtime.js +150 -0
  149. package/dist/projected-document-workspace-action-runtime.js.map +1 -0
  150. package/dist/projected-document-workspace-projection-renderer-diagnostics.d.ts +18 -0
  151. package/dist/projected-document-workspace-projection-renderer-diagnostics.d.ts.map +1 -0
  152. package/dist/projected-document-workspace-projection-renderer-diagnostics.js +207 -0
  153. package/dist/projected-document-workspace-projection-renderer-diagnostics.js.map +1 -0
  154. package/dist/projected-document-workspace-runtime-binding-diagnostics.d.ts +19 -0
  155. package/dist/projected-document-workspace-runtime-binding-diagnostics.d.ts.map +1 -0
  156. package/dist/projected-document-workspace-runtime-binding-diagnostics.js +124 -0
  157. package/dist/projected-document-workspace-runtime-binding-diagnostics.js.map +1 -0
  158. package/dist/projected-navigation-provider.d.ts +16 -0
  159. package/dist/projected-navigation-provider.d.ts.map +1 -0
  160. package/dist/projected-navigation-provider.js +51 -0
  161. package/dist/projected-navigation-provider.js.map +1 -0
  162. package/dist/projected-presentation-flow-host.d.ts +16 -0
  163. package/dist/projected-presentation-flow-host.d.ts.map +1 -0
  164. package/dist/projected-presentation-flow-host.js +14 -0
  165. package/dist/projected-presentation-flow-host.js.map +1 -0
  166. package/dist/projected-query-form-state-adapter.d.ts +12 -0
  167. package/dist/projected-query-form-state-adapter.d.ts.map +1 -0
  168. package/dist/projected-query-form-state-adapter.js +361 -0
  169. package/dist/projected-query-form-state-adapter.js.map +1 -0
  170. package/dist/react-router-binding.d.ts +133 -0
  171. package/dist/react-router-binding.d.ts.map +1 -0
  172. package/dist/react-router-binding.js +76 -0
  173. package/dist/react-router-binding.js.map +1 -0
  174. package/dist/react-router-path.d.ts +4 -0
  175. package/dist/react-router-path.d.ts.map +1 -0
  176. package/dist/react-router-path.js +11 -0
  177. package/dist/react-router-path.js.map +1 -0
  178. package/dist/scope-selection-context.d.ts +28 -0
  179. package/dist/scope-selection-context.d.ts.map +1 -0
  180. package/dist/scope-selection-context.js +13 -0
  181. package/dist/scope-selection-context.js.map +1 -0
  182. package/dist/scope-selection-provider.d.ts +33 -0
  183. package/dist/scope-selection-provider.d.ts.map +1 -0
  184. package/dist/scope-selection-provider.js +162 -0
  185. package/dist/scope-selection-provider.js.map +1 -0
  186. package/dist/scope-selection-request.d.ts +6 -0
  187. package/dist/scope-selection-request.d.ts.map +1 -0
  188. package/dist/scope-selection-request.js +12 -0
  189. package/dist/scope-selection-request.js.map +1 -0
  190. package/dist/standard-navigation-shell-frame-renderers.d.ts +15 -0
  191. package/dist/standard-navigation-shell-frame-renderers.d.ts.map +1 -0
  192. package/dist/standard-navigation-shell-frame-renderers.js +22 -0
  193. package/dist/standard-navigation-shell-frame-renderers.js.map +1 -0
  194. package/dist/standard-navigation-shell-slot-renderers.d.ts +59 -0
  195. package/dist/standard-navigation-shell-slot-renderers.d.ts.map +1 -0
  196. package/dist/standard-navigation-shell-slot-renderers.js +67 -0
  197. package/dist/standard-navigation-shell-slot-renderers.js.map +1 -0
  198. package/dist/view-chrome-slot-renderer-registry.d.ts +12 -0
  199. package/dist/view-chrome-slot-renderer-registry.d.ts.map +1 -0
  200. package/dist/view-chrome-slot-renderer-registry.js +12 -0
  201. package/dist/view-chrome-slot-renderer-registry.js.map +1 -0
  202. package/package.json +60 -0
  203. package/src/collection-chrome-slot-renderer-registry.ts +66 -0
  204. package/src/collection-selection-state-context.ts +51 -0
  205. package/src/collection-selection-state.tsx +101 -0
  206. package/src/document-workspace-runtime.tsx +1505 -0
  207. package/src/index.ts +50 -0
  208. package/src/input-form-endpoint-runtime.ts +632 -0
  209. package/src/local-flow-state-data-source-projection.ts +133 -0
  210. package/src/navigation-runtime-context.ts +40 -0
  211. package/src/navigation-shell-frame-renderer-registry.ts +54 -0
  212. package/src/navigation-shell-region-component-registry.tsx +127 -0
  213. package/src/navigation-shell-slot-renderer-registry.ts +88 -0
  214. package/src/page-host-projection.ts +356 -0
  215. package/src/page-host-renderer-registry.tsx +353 -0
  216. package/src/presentation-action-group-runtime-options.ts +121 -0
  217. package/src/presentation-action-runtime.ts +190 -0
  218. package/src/presentation-data-source-binding-runtime.ts +109 -0
  219. package/src/presentation-data-source-binding.tsx +24 -0
  220. package/src/presentation-flow-runtime.tsx +835 -0
  221. package/src/presentation-module-context.ts +10 -0
  222. package/src/presentation-module-provider.tsx +19 -0
  223. package/src/presentation-projection-diagnostics-context.ts +17 -0
  224. package/src/presentation-projection-diagnostics-hooks.ts +29 -0
  225. package/src/presentation-projection-diagnostics-runtime.tsx +95 -0
  226. package/src/presentation-projection-trace.ts +117 -0
  227. package/src/presentation-query-form-runtime.ts +148 -0
  228. package/src/presentation-query-form-state-adapter-registry.ts +25 -0
  229. package/src/presentation-query-form-state-context.ts +56 -0
  230. package/src/presentation-query-form-state.tsx +250 -0
  231. package/src/presentation-renderer-registry.ts +214 -0
  232. package/src/presentation-standards-context.ts +21 -0
  233. package/src/presentation-standards-provider.tsx +44 -0
  234. package/src/projected-document-action-runtime-bindings.ts +132 -0
  235. package/src/projected-document-action-runtime.ts +414 -0
  236. package/src/projected-document-process-preview-action-runtime-bindings.ts +231 -0
  237. package/src/projected-document-process-preview-action-runtime.ts +1725 -0
  238. package/src/projected-document-process-preview-capability-runtime.ts +216 -0
  239. package/src/projected-document-workspace-action-runtime.ts +402 -0
  240. package/src/projected-document-workspace-projection-renderer-diagnostics.ts +342 -0
  241. package/src/projected-document-workspace-runtime-binding-diagnostics.ts +208 -0
  242. package/src/projected-navigation-provider.tsx +104 -0
  243. package/src/projected-presentation-flow-host.tsx +46 -0
  244. package/src/projected-query-form-state-adapter.ts +578 -0
  245. package/src/react-router-binding.tsx +417 -0
  246. package/src/react-router-path.ts +16 -0
  247. package/src/scope-selection-context.ts +58 -0
  248. package/src/scope-selection-provider.tsx +324 -0
  249. package/src/scope-selection-request.ts +21 -0
  250. package/src/standard-navigation-shell-frame-renderers.tsx +106 -0
  251. package/src/standard-navigation-shell-slot-renderers.tsx +289 -0
  252. package/src/view-chrome-slot-renderer-registry.ts +66 -0
@@ -0,0 +1,10 @@
1
+ import { createContext, useContext } from 'react'
2
+
3
+ import type { PresentationModuleDefinition } from '@cohesivesystems/presentation-core'
4
+
5
+ export const PresentationModuleContext =
6
+ createContext<PresentationModuleDefinition | null>(null)
7
+
8
+ export function usePresentationModule() {
9
+ return useContext(PresentationModuleContext)
10
+ }
@@ -0,0 +1,19 @@
1
+ import { type PropsWithChildren } from 'react'
2
+
3
+ import type { PresentationModuleDefinition } from '@cohesivesystems/presentation-core'
4
+ import { PresentationModuleContext } from './presentation-module-context'
5
+
6
+ export interface PresentationModuleProviderProps extends PropsWithChildren {
7
+ readonly module: PresentationModuleDefinition | null
8
+ }
9
+
10
+ export function PresentationModuleProvider({
11
+ children,
12
+ module,
13
+ }: PresentationModuleProviderProps) {
14
+ return (
15
+ <PresentationModuleContext.Provider value={module}>
16
+ {children}
17
+ </PresentationModuleContext.Provider>
18
+ )
19
+ }
@@ -0,0 +1,17 @@
1
+ import { createContext } from 'react'
2
+
3
+ import type {
4
+ PresentationProjectionDiagnostic,
5
+ } from '@cohesivesystems/presentation-core'
6
+
7
+ export interface PresentationProjectionDiagnosticsRegistry {
8
+ readonly clearDiagnostics: (sourceId: string) => void
9
+ readonly diagnostics: readonly PresentationProjectionDiagnostic[]
10
+ readonly setDiagnostics: (
11
+ sourceId: string,
12
+ diagnostics: readonly PresentationProjectionDiagnostic[],
13
+ ) => void
14
+ }
15
+
16
+ export const PresentationProjectionDiagnosticsContext =
17
+ createContext<PresentationProjectionDiagnosticsRegistry | null>(null)
@@ -0,0 +1,29 @@
1
+ import { useContext, useEffect } from 'react'
2
+
3
+ import {
4
+ PresentationProjectionDiagnosticsContext,
5
+ } from './presentation-projection-diagnostics-context'
6
+ import type {
7
+ PresentationProjectionDiagnostic,
8
+ } from '@cohesivesystems/presentation-core'
9
+
10
+ export function usePresentationProjectionDiagnostics() {
11
+ return useContext(PresentationProjectionDiagnosticsContext)?.diagnostics ?? []
12
+ }
13
+
14
+ export function useRegisterPresentationProjectionDiagnostics(
15
+ sourceId: string,
16
+ diagnostics: readonly PresentationProjectionDiagnostic[],
17
+ ) {
18
+ const registry = useContext(PresentationProjectionDiagnosticsContext)
19
+ const clearDiagnostics = registry?.clearDiagnostics
20
+ const setDiagnostics = registry?.setDiagnostics
21
+
22
+ useEffect(() => {
23
+ setDiagnostics?.(sourceId, diagnostics)
24
+ }, [diagnostics, setDiagnostics, sourceId])
25
+
26
+ useEffect(() => {
27
+ return () => clearDiagnostics?.(sourceId)
28
+ }, [clearDiagnostics, sourceId])
29
+ }
@@ -0,0 +1,95 @@
1
+ import {
2
+ useCallback,
3
+ useMemo,
4
+ useState,
5
+ type ReactNode,
6
+ } from 'react'
7
+
8
+ import {
9
+ PresentationProjectionDiagnosticsContext,
10
+ } from './presentation-projection-diagnostics-context'
11
+ import {
12
+ mergePresentationProjectionDiagnostics,
13
+ type PresentationProjectionDiagnostic,
14
+ } from '@cohesivesystems/presentation-core'
15
+
16
+ interface PresentationProjectionDiagnosticsProviderProps {
17
+ readonly children: ReactNode
18
+ }
19
+
20
+ /**
21
+ * Collects projection diagnostics from local interpreters so developer tooling
22
+ * can render one consolidated view instead of scattering warnings through app
23
+ * chrome.
24
+ */
25
+ export function PresentationProjectionDiagnosticsProvider({
26
+ children,
27
+ }: PresentationProjectionDiagnosticsProviderProps) {
28
+ const [diagnosticsBySource, setDiagnosticsBySource] = useState<
29
+ Readonly<Record<string, readonly PresentationProjectionDiagnostic[]>>
30
+ >({})
31
+ const setDiagnostics = useCallback((
32
+ sourceId: string,
33
+ diagnostics: readonly PresentationProjectionDiagnostic[],
34
+ ) => {
35
+ setDiagnosticsBySource((current) => {
36
+ if (areDiagnosticsEqual(current[sourceId] ?? [], diagnostics)) {
37
+ return current
38
+ }
39
+
40
+ return {
41
+ ...current,
42
+ [sourceId]: [...diagnostics],
43
+ }
44
+ })
45
+ }, [])
46
+ const clearDiagnostics = useCallback((sourceId: string) => {
47
+ setDiagnosticsBySource((current) => {
48
+ if (!current[sourceId]) {
49
+ return current
50
+ }
51
+
52
+ const next = { ...current }
53
+ delete next[sourceId]
54
+ return next
55
+ })
56
+ }, [])
57
+ const diagnostics = useMemo(
58
+ () => mergePresentationProjectionDiagnostics(...Object.values(diagnosticsBySource)),
59
+ [diagnosticsBySource],
60
+ )
61
+ const contextValue = useMemo(
62
+ () => ({
63
+ clearDiagnostics,
64
+ diagnostics,
65
+ setDiagnostics,
66
+ }),
67
+ [clearDiagnostics, diagnostics, setDiagnostics],
68
+ )
69
+
70
+ return (
71
+ <PresentationProjectionDiagnosticsContext.Provider value={contextValue}>
72
+ {children}
73
+ </PresentationProjectionDiagnosticsContext.Provider>
74
+ )
75
+ }
76
+
77
+ function areDiagnosticsEqual(
78
+ left: readonly PresentationProjectionDiagnostic[],
79
+ right: readonly PresentationProjectionDiagnostic[],
80
+ ) {
81
+ if (left.length !== right.length) {
82
+ return false
83
+ }
84
+
85
+ return left.every((diagnostic, index) => {
86
+ const candidate = right[index]
87
+ return Boolean(
88
+ candidate &&
89
+ diagnostic.id === candidate.id &&
90
+ diagnostic.message === candidate.message &&
91
+ diagnostic.severity === candidate.severity &&
92
+ diagnostic.source === candidate.source,
93
+ )
94
+ })
95
+ }
@@ -0,0 +1,117 @@
1
+ import type {
2
+ PresentationBindingDefinition,
3
+ ViewDefinition,
4
+ } from '@cohesivesystems/presentation-core'
5
+ import type {
6
+ NavigationDefinitionProjection,
7
+ } from '@cohesivesystems/presentation-core'
8
+ import {
9
+ createPresentationProjectionTrace as createCorePresentationProjectionTrace,
10
+ } from '@cohesivesystems/presentation-core'
11
+ import {
12
+ resolvePageHostRenderer,
13
+ type PresentationPageHostRendererModuleProjection,
14
+ type SimplePageHostRendererRegistry,
15
+ } from './page-host-renderer-registry'
16
+ import {
17
+ resolvePresentationViewRenderer,
18
+ type PresentationRendererRegistry,
19
+ } from './presentation-renderer-registry'
20
+
21
+ export type {
22
+ PresentationProjectionTrace,
23
+ PresentationProjectionTracePageHost,
24
+ PresentationProjectionTracePageHostRenderer,
25
+ PresentationProjectionTraceRegion,
26
+ PresentationProjectionTraceRoute,
27
+ PresentationProjectionTraceSurface,
28
+ PresentationProjectionTraceView,
29
+ } from '@cohesivesystems/presentation-core'
30
+
31
+ export interface PresentationProjectionTraceModule
32
+ extends PresentationPageHostRendererModuleProjection {
33
+ readonly Targets: readonly {
34
+ readonly Bindings: readonly PresentationBindingDefinition[]
35
+ readonly ComponentSet?: string | null
36
+ readonly Target: string | number
37
+ }[]
38
+ readonly Views: readonly ViewDefinition[]
39
+ }
40
+
41
+ export interface CreatePresentationProjectionTraceOptions<
42
+ TModule extends PresentationProjectionTraceModule,
43
+ TContext,
44
+ > {
45
+ readonly componentSet?: string
46
+ readonly module: TModule | null
47
+ readonly navigation: NavigationDefinitionProjection | null
48
+ readonly pageHostRendererRegistry?: SimplePageHostRendererRegistry<
49
+ TModule,
50
+ TContext
51
+ >
52
+ readonly pathname: string
53
+ readonly rendererRegistry?: PresentationRendererRegistry<TContext>
54
+ }
55
+
56
+ /**
57
+ * Builds a read-only projection trace while adapting React renderer
58
+ * registries into framework-neutral trace resolver results.
59
+ */
60
+ export function createPresentationProjectionTrace<
61
+ TModule extends PresentationProjectionTraceModule,
62
+ TContext = unknown,
63
+ >({
64
+ componentSet,
65
+ module,
66
+ navigation,
67
+ pageHostRendererRegistry,
68
+ pathname,
69
+ rendererRegistry,
70
+ }: CreatePresentationProjectionTraceOptions<TModule, TContext>) {
71
+ return createCorePresentationProjectionTrace({
72
+ componentSet,
73
+ module,
74
+ navigation,
75
+ pathname,
76
+ resolvePageHostRenderer: pageHostRendererRegistry
77
+ ? ({ module, pageHost, route }) => {
78
+ const resolution = resolvePageHostRenderer({
79
+ componentKey: null,
80
+ componentSet,
81
+ module,
82
+ pageHost,
83
+ registry: pageHostRendererRegistry,
84
+ route,
85
+ })
86
+
87
+ return {
88
+ componentKey: resolution.componentKey,
89
+ componentRole: resolution.componentRole,
90
+ rendererKey: resolution.rendererKey,
91
+ resolutionSource: resolution.resolutionSource,
92
+ semanticRole: resolution.semanticRole,
93
+ targetBindingSource: resolution.targetBindingSource,
94
+ }
95
+ }
96
+ : undefined,
97
+ resolveViewRenderer: rendererRegistry
98
+ ? ({ module, routeId, view }) => {
99
+ const resolution = resolvePresentationViewRenderer({
100
+ componentSet,
101
+ module,
102
+ registry: rendererRegistry,
103
+ routeId,
104
+ view,
105
+ })
106
+
107
+ return {
108
+ componentKey: resolution.componentKey,
109
+ componentRole: resolution.componentRole,
110
+ rendererResolved: Boolean(resolution.renderer),
111
+ resolutionSource: resolution.resolutionSource,
112
+ semanticRole: resolution.semanticRole,
113
+ }
114
+ }
115
+ : undefined,
116
+ })
117
+ }
@@ -0,0 +1,148 @@
1
+ import type { Dispatch, SetStateAction } from 'react'
2
+
3
+ import type {
4
+ ProjectedQueryFormActionContext,
5
+ ProjectedQueryFormRuntime,
6
+ ProjectedQueryFormValueChangeContext,
7
+ QueryFormDefinition,
8
+ } from '@cohesivesystems/presentation-core'
9
+ import { queryFormExecutionModes } from '@cohesivesystems/presentation-contracts'
10
+
11
+ const debouncedDraftExecutionTimers = new Map<string, ReturnType<typeof setTimeout>>()
12
+
13
+ export type {
14
+ PresentationQueryFormState,
15
+ PresentationQueryFormStateMap,
16
+ ProjectedQueryFormActionContext,
17
+ ProjectedQueryFormRuntime,
18
+ ProjectedQueryFormValueChangeContext,
19
+ } from '@cohesivesystems/presentation-core'
20
+
21
+ export {
22
+ findPresentationQueryFormStateForDataSource,
23
+ readPresentationQueryFormAppliedValue,
24
+ readPresentationQueryFormDraftValue,
25
+ } from '@cohesivesystems/presentation-core'
26
+
27
+ export interface PresentationQueryFormValueContext<TValue extends object> {
28
+ readonly choiceValuesByFieldId: Readonly<Record<string, readonly string[]>>
29
+ readonly queryForm: QueryFormDefinition
30
+ readonly value: TValue
31
+ }
32
+
33
+ export interface CreatePresentationQueryFormRuntimeOptions<TValue extends object> {
34
+ readonly applyValue: (context: PresentationQueryFormValueContext<TValue>) => void
35
+ readonly createDefaultValue: (context: PresentationQueryFormValueContext<TValue>) => TValue
36
+ readonly normalizeValue?: (context: PresentationQueryFormValueContext<TValue>) => TValue
37
+ readonly queryForm: QueryFormDefinition | null
38
+ readonly setDraftValue: Dispatch<SetStateAction<TValue>>
39
+ readonly value: TValue
40
+ }
41
+
42
+ /**
43
+ * Adapts caller-owned state into the projected query-form runtime contract.
44
+ *
45
+ * The presentation IR defines when a query form has an applied result state,
46
+ * URL state, and execution policy. This helper keeps the generic form actions
47
+ * semantic: apply normalizes the draft and commits it to the result state,
48
+ * reset computes the form default from the available choices and commits that
49
+ * same value. Concrete hosts provide the interpretation for the commit itself,
50
+ * such as URL updates, pagination reset, or data-source invalidation.
51
+ */
52
+ export function createPresentationQueryFormRuntime<TValue extends object>({
53
+ applyValue,
54
+ createDefaultValue,
55
+ normalizeValue,
56
+ queryForm,
57
+ setDraftValue,
58
+ value,
59
+ }: CreatePresentationQueryFormRuntimeOptions<TValue>): ProjectedQueryFormRuntime<TValue> | null {
60
+ if (!queryForm) {
61
+ return null
62
+ }
63
+
64
+ const normalize = (context: PresentationQueryFormValueContext<TValue>) =>
65
+ normalizeValue ? normalizeValue(context) : context.value
66
+ const commit = (context: PresentationQueryFormValueContext<TValue>) => {
67
+ const nextValue = normalize(context)
68
+ setDraftValue(nextValue)
69
+ applyValue({ ...context, value: nextValue })
70
+ }
71
+
72
+ return {
73
+ apply: (context) =>
74
+ commit(createQueryFormValueContext(queryForm, context, context.value)),
75
+ reset: (context) => {
76
+ const resetContext = createQueryFormValueContext(queryForm, context, context.value)
77
+ const nextValue = createDefaultValue(resetContext)
78
+ commit({ ...resetContext, value: nextValue })
79
+ },
80
+ setValue: (update, context) => {
81
+ const nextValue = resolveSetStateValue(update, value)
82
+ setDraftValue(nextValue)
83
+
84
+ if (context) {
85
+ executeQueryFormDraftChange(
86
+ queryForm,
87
+ commit,
88
+ createQueryFormValueContext(queryForm, context, nextValue),
89
+ )
90
+ }
91
+ },
92
+ value,
93
+ }
94
+ }
95
+
96
+ export function shouldExecuteQueryFormOnDraftChange(queryForm: QueryFormDefinition | null) {
97
+ return queryForm?.Target.State.Execution.Mode === queryFormExecutionModes.live ||
98
+ queryForm?.Target.State.Execution.Mode === queryFormExecutionModes.debouncedLive
99
+ }
100
+
101
+ function createQueryFormValueContext<TValue extends object>(
102
+ queryForm: QueryFormDefinition,
103
+ context: ProjectedQueryFormActionContext<TValue> | ProjectedQueryFormValueChangeContext<TValue>,
104
+ value: TValue,
105
+ ): PresentationQueryFormValueContext<TValue> {
106
+ return {
107
+ choiceValuesByFieldId: context.choiceValuesByFieldId,
108
+ queryForm,
109
+ value,
110
+ }
111
+ }
112
+
113
+ function executeQueryFormDraftChange<TValue extends object>(
114
+ queryForm: QueryFormDefinition,
115
+ commit: (context: PresentationQueryFormValueContext<TValue>) => void,
116
+ context: PresentationQueryFormValueContext<TValue>,
117
+ ) {
118
+ const execution = queryForm.Target.State.Execution
119
+ if (execution.Mode === queryFormExecutionModes.live) {
120
+ commit(context)
121
+ return
122
+ }
123
+
124
+ if (execution.Mode === queryFormExecutionModes.debouncedLive) {
125
+ const key = queryForm.Target.State.StateId || queryForm.Id
126
+ const previousTimer = debouncedDraftExecutionTimers.get(key)
127
+ if (previousTimer) {
128
+ clearTimeout(previousTimer)
129
+ }
130
+
131
+ debouncedDraftExecutionTimers.set(
132
+ key,
133
+ setTimeout(() => {
134
+ debouncedDraftExecutionTimers.delete(key)
135
+ commit(context)
136
+ }, execution.DebounceMilliseconds ?? 250),
137
+ )
138
+ }
139
+ }
140
+
141
+ function resolveSetStateValue<TValue extends object>(
142
+ update: TValue | ((current: TValue) => TValue),
143
+ current: TValue,
144
+ ) {
145
+ return typeof update === 'function'
146
+ ? (update as (current: TValue) => TValue)(current)
147
+ : update
148
+ }
@@ -0,0 +1,25 @@
1
+ import type { PresentationModuleDefinition } from '@cohesivesystems/presentation-core'
2
+ import type {
3
+ PresentationQueryFormStateAdapter,
4
+ PresentationQueryFormStateAdapterRegistry,
5
+ } from './presentation-query-form-state'
6
+ import { createProjectedQueryFormStateAdapter } from './projected-query-form-state-adapter'
7
+
8
+ export function resolvePresentationQueryFormStateAdapters(
9
+ module: PresentationModuleDefinition | null,
10
+ registry: PresentationQueryFormStateAdapterRegistry,
11
+ ): readonly PresentationQueryFormStateAdapter[] {
12
+ if (!module) {
13
+ return Object.values(registry).filter(isPresentationQueryFormStateAdapter)
14
+ }
15
+
16
+ return module.QueryForms
17
+ .map((queryForm) => registry[queryForm.Id] ?? createProjectedQueryFormStateAdapter(queryForm.Id))
18
+ .filter(isPresentationQueryFormStateAdapter)
19
+ }
20
+
21
+ function isPresentationQueryFormStateAdapter(
22
+ value: PresentationQueryFormStateAdapter | undefined,
23
+ ): value is PresentationQueryFormStateAdapter {
24
+ return Boolean(value)
25
+ }
@@ -0,0 +1,56 @@
1
+ import {
2
+ createContext,
3
+ useContext,
4
+ type Dispatch,
5
+ type SetStateAction,
6
+ } from 'react'
7
+
8
+ import type {
9
+ InputFormDefinition,
10
+ PresentationQueryFormStateMap,
11
+ QueryFormDefinition,
12
+ } from '@cohesivesystems/presentation-core'
13
+
14
+ export interface PresentationQueryFormStateEntry<TValue = unknown> {
15
+ readonly appliedValue: TValue
16
+ readonly draftValue: TValue
17
+ readonly inputForm: InputFormDefinition | null
18
+ readonly queryForm: QueryFormDefinition | null
19
+ readonly queryFormId: string
20
+ readonly setAppliedValue: Dispatch<SetStateAction<TValue>>
21
+ readonly setDraftValue: Dispatch<SetStateAction<TValue>>
22
+ }
23
+
24
+ export interface PresentationQueryFormStateContextValue {
25
+ readonly entries: Readonly<Record<string, PresentationQueryFormStateEntry>>
26
+ readonly queryFormStates: PresentationQueryFormStateMap
27
+ }
28
+
29
+ export const PresentationQueryFormStateContext =
30
+ createContext<PresentationQueryFormStateContextValue | null>(null)
31
+
32
+ export function usePresentationQueryFormState<TValue = unknown>(
33
+ queryFormId: string,
34
+ ) {
35
+ const context = useRequiredPresentationQueryFormStateContext()
36
+ return context.entries[queryFormId] as
37
+ | PresentationQueryFormStateEntry<TValue>
38
+ | undefined
39
+ }
40
+
41
+ export function usePresentationQueryFormStateMap() {
42
+ return useRequiredPresentationQueryFormStateContext().queryFormStates
43
+ }
44
+
45
+ export function usePresentationQueryFormStateEntries() {
46
+ return useRequiredPresentationQueryFormStateContext().entries
47
+ }
48
+
49
+ function useRequiredPresentationQueryFormStateContext() {
50
+ const context = useContext(PresentationQueryFormStateContext)
51
+ if (!context) {
52
+ throw new Error('Presentation query form state must be used inside PresentationQueryFormStateProvider.')
53
+ }
54
+
55
+ return context
56
+ }