@pwfabric/runtime 0.0.0-stage → 1.0.0-rc.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 (447) hide show
  1. package/LICENSE +90 -0
  2. package/README.md +43 -2
  3. package/dist/a11y/announcer.d.ts +65 -0
  4. package/dist/a11y/announcer.js +140 -0
  5. package/dist/a11y/announcer.js.map +1 -0
  6. package/dist/a11y/contrast.d.ts +54 -0
  7. package/dist/a11y/contrast.js +93 -0
  8. package/dist/a11y/contrast.js.map +1 -0
  9. package/dist/a11y/focus.d.ts +123 -0
  10. package/dist/a11y/focus.js +282 -0
  11. package/dist/a11y/focus.js.map +1 -0
  12. package/dist/a11y/index.d.ts +21 -0
  13. package/dist/a11y/index.js +18 -0
  14. package/dist/a11y/index.js.map +1 -0
  15. package/dist/a11y/keyboard.d.ts +144 -0
  16. package/dist/a11y/keyboard.js +317 -0
  17. package/dist/a11y/keyboard.js.map +1 -0
  18. package/dist/adapters/default-image.d.ts +25 -0
  19. package/dist/adapters/default-image.js +37 -0
  20. package/dist/adapters/default-image.js.map +1 -0
  21. package/dist/adapters/index.d.ts +27 -0
  22. package/dist/adapters/index.js +28 -0
  23. package/dist/adapters/index.js.map +1 -0
  24. package/dist/adapters/next-image.d.ts +38 -0
  25. package/dist/adapters/next-image.js +124 -0
  26. package/dist/adapters/next-image.js.map +1 -0
  27. package/dist/adapters/types.d.ts +61 -0
  28. package/dist/adapters/types.js +11 -0
  29. package/dist/adapters/types.js.map +1 -0
  30. package/dist/analytics/index.d.ts +14 -0
  31. package/dist/analytics/index.js +15 -0
  32. package/dist/analytics/index.js.map +1 -0
  33. package/dist/analytics/tracker.d.ts +65 -0
  34. package/dist/analytics/tracker.js +251 -0
  35. package/dist/analytics/tracker.js.map +1 -0
  36. package/dist/analytics/types.d.ts +130 -0
  37. package/dist/analytics/types.js +11 -0
  38. package/dist/analytics/types.js.map +1 -0
  39. package/dist/auth/index.d.ts +15 -0
  40. package/dist/auth/index.js +14 -0
  41. package/dist/auth/index.js.map +1 -0
  42. package/dist/auth/provider.d.ts +132 -0
  43. package/dist/auth/provider.js +473 -0
  44. package/dist/auth/provider.js.map +1 -0
  45. package/dist/auth/types.d.ts +117 -0
  46. package/dist/auth/types.js +9 -0
  47. package/dist/auth/types.js.map +1 -0
  48. package/dist/binding/collection.d.ts +190 -0
  49. package/dist/binding/collection.js +358 -0
  50. package/dist/binding/collection.js.map +1 -0
  51. package/dist/binding/datasource.d.ts +319 -0
  52. package/dist/binding/datasource.js +556 -0
  53. package/dist/binding/datasource.js.map +1 -0
  54. package/dist/binding/engine.d.ts +65 -0
  55. package/dist/binding/engine.js +268 -0
  56. package/dist/binding/engine.js.map +1 -0
  57. package/dist/binding/expression.d.ts +150 -0
  58. package/dist/binding/expression.js +787 -0
  59. package/dist/binding/expression.js.map +1 -0
  60. package/dist/binding/index.d.ts +19 -0
  61. package/dist/binding/index.js +14 -0
  62. package/dist/binding/index.js.map +1 -0
  63. package/dist/binding/two-way.d.ts +149 -0
  64. package/dist/binding/two-way.js +462 -0
  65. package/dist/binding/two-way.js.map +1 -0
  66. package/dist/binding/types.d.ts +119 -0
  67. package/dist/binding/types.js +9 -0
  68. package/dist/binding/types.js.map +1 -0
  69. package/dist/blocks/component-types.d.ts +81 -0
  70. package/dist/blocks/component-types.js +11 -0
  71. package/dist/blocks/component-types.js.map +1 -0
  72. package/dist/blocks/composition-rules.d.ts +168 -0
  73. package/dist/blocks/composition-rules.js +391 -0
  74. package/dist/blocks/composition-rules.js.map +1 -0
  75. package/dist/blocks/hooks.d.ts +31 -0
  76. package/dist/blocks/hooks.js +42 -0
  77. package/dist/blocks/hooks.js.map +1 -0
  78. package/dist/blocks/index.d.ts +14 -0
  79. package/dist/blocks/index.js +23 -0
  80. package/dist/blocks/index.js.map +1 -0
  81. package/dist/blocks/registry.d.ts +84 -0
  82. package/dist/blocks/registry.js +136 -0
  83. package/dist/blocks/registry.js.map +1 -0
  84. package/dist/blocks/rule-engine.d.ts +131 -0
  85. package/dist/blocks/rule-engine.js +321 -0
  86. package/dist/blocks/rule-engine.js.map +1 -0
  87. package/dist/blocks/surface-event-context.d.ts +13 -0
  88. package/dist/blocks/surface-event-context.js +14 -0
  89. package/dist/blocks/surface-event-context.js.map +1 -0
  90. package/dist/blocks/surface-id-context.d.ts +13 -0
  91. package/dist/blocks/surface-id-context.js +15 -0
  92. package/dist/blocks/surface-id-context.js.map +1 -0
  93. package/dist/bus.d.ts +41 -0
  94. package/dist/bus.js +158 -0
  95. package/dist/bus.js.map +1 -0
  96. package/dist/cache/index.d.ts +9 -0
  97. package/dist/cache/index.js +10 -0
  98. package/dist/cache/index.js.map +1 -0
  99. package/dist/cache/memory.d.ts +32 -0
  100. package/dist/cache/memory.js +138 -0
  101. package/dist/cache/memory.js.map +1 -0
  102. package/dist/cache/types.d.ts +62 -0
  103. package/dist/cache/types.js +9 -0
  104. package/dist/cache/types.js.map +1 -0
  105. package/dist/capability/index.d.ts +72 -0
  106. package/dist/capability/index.js +87 -0
  107. package/dist/capability/index.js.map +1 -0
  108. package/dist/capability/kernel-capabilities.d.ts +31 -0
  109. package/dist/capability/kernel-capabilities.js +36 -0
  110. package/dist/capability/kernel-capabilities.js.map +1 -0
  111. package/dist/capability/platform-capabilities.d.ts +71 -0
  112. package/dist/capability/platform-capabilities.js +267 -0
  113. package/dist/capability/platform-capabilities.js.map +1 -0
  114. package/dist/capability/type-mapping.d.ts +70 -0
  115. package/dist/capability/type-mapping.js +107 -0
  116. package/dist/capability/type-mapping.js.map +1 -0
  117. package/dist/capability/validation.d.ts +46 -0
  118. package/dist/capability/validation.js +54 -0
  119. package/dist/capability/validation.js.map +1 -0
  120. package/dist/connectors/declared-connector.d.ts +48 -0
  121. package/dist/connectors/declared-connector.js +333 -0
  122. package/dist/connectors/declared-connector.js.map +1 -0
  123. package/dist/connectors/engine-registry.d.ts +50 -0
  124. package/dist/connectors/engine-registry.js +135 -0
  125. package/dist/connectors/engine-registry.js.map +1 -0
  126. package/dist/connectors/index.d.ts +14 -0
  127. package/dist/connectors/index.js +14 -0
  128. package/dist/connectors/index.js.map +1 -0
  129. package/dist/connectors/module-loader.d.ts +70 -0
  130. package/dist/connectors/module-loader.js +143 -0
  131. package/dist/connectors/module-loader.js.map +1 -0
  132. package/dist/connectors/types.d.ts +174 -0
  133. package/dist/connectors/types.js +23 -0
  134. package/dist/connectors/types.js.map +1 -0
  135. package/dist/context.d.ts +27 -0
  136. package/dist/context.js +38 -0
  137. package/dist/context.js.map +1 -0
  138. package/dist/data/DataCapabilityProvider.d.ts +39 -0
  139. package/dist/data/DataCapabilityProvider.js +58 -0
  140. package/dist/data/DataCapabilityProvider.js.map +1 -0
  141. package/dist/data/index.d.ts +17 -0
  142. package/dist/data/index.js +18 -0
  143. package/dist/data/index.js.map +1 -0
  144. package/dist/data/manager.d.ts +40 -0
  145. package/dist/data/manager.js +442 -0
  146. package/dist/data/manager.js.map +1 -0
  147. package/dist/data/types.d.ts +218 -0
  148. package/dist/data/types.js +2 -0
  149. package/dist/data/types.js.map +1 -0
  150. package/dist/entity/aggregate.d.ts +8 -0
  151. package/dist/entity/aggregate.js +24 -0
  152. package/dist/entity/aggregate.js.map +1 -0
  153. package/dist/entity/apply-query.d.ts +58 -0
  154. package/dist/entity/apply-query.js +264 -0
  155. package/dist/entity/apply-query.js.map +1 -0
  156. package/dist/entity/behavior.d.ts +94 -0
  157. package/dist/entity/behavior.js +78 -0
  158. package/dist/entity/behavior.js.map +1 -0
  159. package/dist/entity/connector.d.ts +141 -0
  160. package/dist/entity/connector.js +89 -0
  161. package/dist/entity/connector.js.map +1 -0
  162. package/dist/entity/connectors/index.d.ts +12 -0
  163. package/dist/entity/connectors/index.js +11 -0
  164. package/dist/entity/connectors/index.js.map +1 -0
  165. package/dist/entity/connectors/static.d.ts +51 -0
  166. package/dist/entity/connectors/static.js +245 -0
  167. package/dist/entity/connectors/static.js.map +1 -0
  168. package/dist/entity/entity-datasource.d.ts +50 -0
  169. package/dist/entity/entity-datasource.js +33 -0
  170. package/dist/entity/entity-datasource.js.map +1 -0
  171. package/dist/entity/facade.d.ts +70 -0
  172. package/dist/entity/facade.js +70 -0
  173. package/dist/entity/facade.js.map +1 -0
  174. package/dist/entity/http-connector.d.ts +123 -0
  175. package/dist/entity/http-connector.js +295 -0
  176. package/dist/entity/http-connector.js.map +1 -0
  177. package/dist/entity/index.d.ts +38 -0
  178. package/dist/entity/index.js +31 -0
  179. package/dist/entity/index.js.map +1 -0
  180. package/dist/entity/postgres-connector.d.ts +64 -0
  181. package/dist/entity/postgres-connector.js +239 -0
  182. package/dist/entity/postgres-connector.js.map +1 -0
  183. package/dist/entity/registry.d.ts +59 -0
  184. package/dist/entity/registry.js +90 -0
  185. package/dist/entity/registry.js.map +1 -0
  186. package/dist/entity/store.d.ts +66 -0
  187. package/dist/entity/store.js +349 -0
  188. package/dist/entity/store.js.map +1 -0
  189. package/dist/entity/types.d.ts +180 -0
  190. package/dist/entity/types.js +10 -0
  191. package/dist/entity/types.js.map +1 -0
  192. package/dist/execution-context.d.ts +88 -0
  193. package/dist/execution-context.js +146 -0
  194. package/dist/execution-context.js.map +1 -0
  195. package/dist/executor.d.ts +27 -0
  196. package/dist/executor.js +33 -0
  197. package/dist/executor.js.map +1 -0
  198. package/dist/forms/form-entity-bridge.d.ts +94 -0
  199. package/dist/forms/form-entity-bridge.js +96 -0
  200. package/dist/forms/form-entity-bridge.js.map +1 -0
  201. package/dist/forms/form-write-target.d.ts +34 -0
  202. package/dist/forms/form-write-target.js +81 -0
  203. package/dist/forms/form-write-target.js.map +1 -0
  204. package/dist/forms/index.d.ts +22 -0
  205. package/dist/forms/index.js +25 -0
  206. package/dist/forms/index.js.map +1 -0
  207. package/dist/forms/named-control-values.d.ts +27 -0
  208. package/dist/forms/named-control-values.js +42 -0
  209. package/dist/forms/named-control-values.js.map +1 -0
  210. package/dist/forms/processor.d.ts +55 -0
  211. package/dist/forms/processor.js +154 -0
  212. package/dist/forms/processor.js.map +1 -0
  213. package/dist/forms/types.d.ts +174 -0
  214. package/dist/forms/types.js +33 -0
  215. package/dist/forms/types.js.map +1 -0
  216. package/dist/forms/validator.d.ts +61 -0
  217. package/dist/forms/validator.js +218 -0
  218. package/dist/forms/validator.js.map +1 -0
  219. package/dist/graph/index.d.ts +10 -0
  220. package/dist/graph/index.js +9 -0
  221. package/dist/graph/index.js.map +1 -0
  222. package/dist/graph/resolver.d.ts +66 -0
  223. package/dist/graph/resolver.js +243 -0
  224. package/dist/graph/resolver.js.map +1 -0
  225. package/dist/graph/types.d.ts +125 -0
  226. package/dist/graph/types.js +9 -0
  227. package/dist/graph/types.js.map +1 -0
  228. package/dist/hooks/useInstalledAtoms.d.ts +96 -0
  229. package/dist/hooks/useInstalledAtoms.js +92 -0
  230. package/dist/hooks/useInstalledAtoms.js.map +1 -0
  231. package/dist/i18n/index.d.ts +15 -0
  232. package/dist/i18n/index.js +14 -0
  233. package/dist/i18n/index.js.map +1 -0
  234. package/dist/i18n/translator.d.ts +76 -0
  235. package/dist/i18n/translator.js +357 -0
  236. package/dist/i18n/translator.js.map +1 -0
  237. package/dist/i18n/types.d.ts +93 -0
  238. package/dist/i18n/types.js +9 -0
  239. package/dist/i18n/types.js.map +1 -0
  240. package/dist/index.d.ts +64 -0
  241. package/dist/index.js +95 -0
  242. package/dist/index.js.map +1 -0
  243. package/dist/kernel.d.ts +47 -0
  244. package/dist/kernel.js +258 -0
  245. package/dist/kernel.js.map +1 -0
  246. package/dist/perf/budget.d.ts +92 -0
  247. package/dist/perf/budget.js +122 -0
  248. package/dist/perf/budget.js.map +1 -0
  249. package/dist/perf/index.d.ts +16 -0
  250. package/dist/perf/index.js +13 -0
  251. package/dist/perf/index.js.map +1 -0
  252. package/dist/perf/render-timer.d.ts +90 -0
  253. package/dist/perf/render-timer.js +136 -0
  254. package/dist/perf/render-timer.js.map +1 -0
  255. package/dist/perf/reporter.d.ts +126 -0
  256. package/dist/perf/reporter.js +241 -0
  257. package/dist/perf/reporter.js.map +1 -0
  258. package/dist/perf/web-vitals.d.ts +111 -0
  259. package/dist/perf/web-vitals.js +268 -0
  260. package/dist/perf/web-vitals.js.map +1 -0
  261. package/dist/registry.d.ts +63 -0
  262. package/dist/registry.js +126 -0
  263. package/dist/registry.js.map +1 -0
  264. package/dist/render/BehaviorSurfaceProvider.d.ts +65 -0
  265. package/dist/render/BehaviorSurfaceProvider.js +185 -0
  266. package/dist/render/BehaviorSurfaceProvider.js.map +1 -0
  267. package/dist/render/BlockErrorBoundary.d.ts +26 -0
  268. package/dist/render/BlockErrorBoundary.js +41 -0
  269. package/dist/render/BlockErrorBoundary.js.map +1 -0
  270. package/dist/render/DataBoundSurfaceRenderer.d.ts +78 -0
  271. package/dist/render/DataBoundSurfaceRenderer.js +998 -0
  272. package/dist/render/DataBoundSurfaceRenderer.js.map +1 -0
  273. package/dist/render/DynamicBlockWrapper.d.ts +23 -0
  274. package/dist/render/DynamicBlockWrapper.js +117 -0
  275. package/dist/render/DynamicBlockWrapper.js.map +1 -0
  276. package/dist/render/appearance-resolver.d.ts +50 -0
  277. package/dist/render/appearance-resolver.js +78 -0
  278. package/dist/render/appearance-resolver.js.map +1 -0
  279. package/dist/render/capability-gate.d.ts +69 -0
  280. package/dist/render/capability-gate.js +94 -0
  281. package/dist/render/capability-gate.js.map +1 -0
  282. package/dist/render/conditional-states-css.d.ts +41 -0
  283. package/dist/render/conditional-states-css.js +82 -0
  284. package/dist/render/conditional-states-css.js.map +1 -0
  285. package/dist/render/connections-context.d.ts +31 -0
  286. package/dist/render/connections-context.js +34 -0
  287. package/dist/render/connections-context.js.map +1 -0
  288. package/dist/render/dark-theme-css.d.ts +36 -0
  289. package/dist/render/dark-theme-css.js +67 -0
  290. package/dist/render/dark-theme-css.js.map +1 -0
  291. package/dist/render/data-binding-types.d.ts +191 -0
  292. package/dist/render/data-binding-types.js +11 -0
  293. package/dist/render/data-binding-types.js.map +1 -0
  294. package/dist/render/data-cache.d.ts +30 -0
  295. package/dist/render/data-cache.js +37 -0
  296. package/dist/render/data-cache.js.map +1 -0
  297. package/dist/render/derive-dark-theme.d.ts +17 -0
  298. package/dist/render/derive-dark-theme.js +18 -0
  299. package/dist/render/derive-dark-theme.js.map +1 -0
  300. package/dist/render/dynamic-artifact-context.d.ts +77 -0
  301. package/dist/render/dynamic-artifact-context.js +89 -0
  302. package/dist/render/dynamic-artifact-context.js.map +1 -0
  303. package/dist/render/dynamic-block-loader.d.ts +80 -0
  304. package/dist/render/dynamic-block-loader.js +197 -0
  305. package/dist/render/dynamic-block-loader.js.map +1 -0
  306. package/dist/render/endpoint.d.ts +18 -0
  307. package/dist/render/endpoint.js +109 -0
  308. package/dist/render/endpoint.js.map +1 -0
  309. package/dist/render/entity-facade-context.d.ts +34 -0
  310. package/dist/render/entity-facade-context.js +37 -0
  311. package/dist/render/entity-facade-context.js.map +1 -0
  312. package/dist/render/group-states-css.d.ts +41 -0
  313. package/dist/render/group-states-css.js +73 -0
  314. package/dist/render/group-states-css.js.map +1 -0
  315. package/dist/render/hooks/useSurfaceEvents.d.ts +8 -0
  316. package/dist/render/hooks/useSurfaceEvents.js +9 -0
  317. package/dist/render/hooks/useSurfaceEvents.js.map +1 -0
  318. package/dist/render/hooks/useSurfaceId.d.ts +8 -0
  319. package/dist/render/hooks/useSurfaceId.js +9 -0
  320. package/dist/render/hooks/useSurfaceId.js.map +1 -0
  321. package/dist/render/index.d.ts +48 -0
  322. package/dist/render/index.js +61 -0
  323. package/dist/render/index.js.map +1 -0
  324. package/dist/render/interaction-rule-engine.d.ts +12 -0
  325. package/dist/render/interaction-rule-engine.js +47 -0
  326. package/dist/render/interaction-rule-engine.js.map +1 -0
  327. package/dist/render/keyframes-css.d.ts +31 -0
  328. package/dist/render/keyframes-css.js +44 -0
  329. package/dist/render/keyframes-css.js.map +1 -0
  330. package/dist/render/query-state.d.ts +3 -0
  331. package/dist/render/query-state.js +70 -0
  332. package/dist/render/query-state.js.map +1 -0
  333. package/dist/render/renderer.d.ts +44 -0
  334. package/dist/render/renderer.js +937 -0
  335. package/dist/render/renderer.js.map +1 -0
  336. package/dist/render/resolve-expressions.d.ts +37 -0
  337. package/dist/render/resolve-expressions.js +309 -0
  338. package/dist/render/resolve-expressions.js.map +1 -0
  339. package/dist/render/responsive-style-css.d.ts +42 -0
  340. package/dist/render/responsive-style-css.js +123 -0
  341. package/dist/render/responsive-style-css.js.map +1 -0
  342. package/dist/render/responsive.d.ts +49 -0
  343. package/dist/render/responsive.js +99 -0
  344. package/dist/render/responsive.js.map +1 -0
  345. package/dist/render/scoped-css.d.ts +71 -0
  346. package/dist/render/scoped-css.js +102 -0
  347. package/dist/render/scoped-css.js.map +1 -0
  348. package/dist/render/shell-selection.d.ts +69 -0
  349. package/dist/render/shell-selection.js +117 -0
  350. package/dist/render/shell-selection.js.map +1 -0
  351. package/dist/render/states-css.d.ts +32 -0
  352. package/dist/render/states-css.js +63 -0
  353. package/dist/render/states-css.js.map +1 -0
  354. package/dist/render/surface-data-context.d.ts +18 -0
  355. package/dist/render/surface-data-context.js +21 -0
  356. package/dist/render/surface-data-context.js.map +1 -0
  357. package/dist/render/surface-event-bus.d.ts +19 -0
  358. package/dist/render/surface-event-bus.js +68 -0
  359. package/dist/render/surface-event-bus.js.map +1 -0
  360. package/dist/render/surface-event-context.d.ts +11 -0
  361. package/dist/render/surface-event-context.js +12 -0
  362. package/dist/render/surface-event-context.js.map +1 -0
  363. package/dist/render/surface-id-context.d.ts +8 -0
  364. package/dist/render/surface-id-context.js +9 -0
  365. package/dist/render/surface-id-context.js.map +1 -0
  366. package/dist/render/theme-utils.d.ts +14 -0
  367. package/dist/render/theme-utils.js +15 -0
  368. package/dist/render/theme-utils.js.map +1 -0
  369. package/dist/render/types.d.ts +282 -0
  370. package/dist/render/types.js +9 -0
  371. package/dist/render/types.js.map +1 -0
  372. package/dist/render/visibility-css.d.ts +42 -0
  373. package/dist/render/visibility-css.js +119 -0
  374. package/dist/render/visibility-css.js.map +1 -0
  375. package/dist/render/width-scope.d.ts +34 -0
  376. package/dist/render/width-scope.js +44 -0
  377. package/dist/render/width-scope.js.map +1 -0
  378. package/dist/render/write-only-sources.d.ts +33 -0
  379. package/dist/render/write-only-sources.js +99 -0
  380. package/dist/render/write-only-sources.js.map +1 -0
  381. package/dist/routing/index.d.ts +14 -0
  382. package/dist/routing/index.js +15 -0
  383. package/dist/routing/index.js.map +1 -0
  384. package/dist/routing/router.d.ts +42 -0
  385. package/dist/routing/router.js +218 -0
  386. package/dist/routing/router.js.map +1 -0
  387. package/dist/routing/types.d.ts +124 -0
  388. package/dist/routing/types.js +9 -0
  389. package/dist/routing/types.js.map +1 -0
  390. package/dist/seo/generator.d.ts +39 -0
  391. package/dist/seo/generator.js +236 -0
  392. package/dist/seo/generator.js.map +1 -0
  393. package/dist/seo/index.d.ts +14 -0
  394. package/dist/seo/index.js +15 -0
  395. package/dist/seo/index.js.map +1 -0
  396. package/dist/seo/types.d.ts +181 -0
  397. package/dist/seo/types.js +9 -0
  398. package/dist/seo/types.js.map +1 -0
  399. package/dist/state/index.d.ts +15 -0
  400. package/dist/state/index.js +16 -0
  401. package/dist/state/index.js.map +1 -0
  402. package/dist/state/manager.d.ts +33 -0
  403. package/dist/state/manager.js +81 -0
  404. package/dist/state/manager.js.map +1 -0
  405. package/dist/state/store.d.ts +40 -0
  406. package/dist/state/store.js +145 -0
  407. package/dist/state/store.js.map +1 -0
  408. package/dist/state/types.d.ts +107 -0
  409. package/dist/state/types.js +9 -0
  410. package/dist/state/types.js.map +1 -0
  411. package/dist/surface/expression.d.ts +65 -0
  412. package/dist/surface/expression.js +179 -0
  413. package/dist/surface/expression.js.map +1 -0
  414. package/dist/surface/index.d.ts +32 -0
  415. package/dist/surface/index.js +25 -0
  416. package/dist/surface/index.js.map +1 -0
  417. package/dist/surface/interpreter.d.ts +96 -0
  418. package/dist/surface/interpreter.js +231 -0
  419. package/dist/surface/interpreter.js.map +1 -0
  420. package/dist/surface/layout.d.ts +54 -0
  421. package/dist/surface/layout.js +288 -0
  422. package/dist/surface/layout.js.map +1 -0
  423. package/dist/surface/output.d.ts +90 -0
  424. package/dist/surface/output.js +104 -0
  425. package/dist/surface/output.js.map +1 -0
  426. package/dist/surface/primitives.d.ts +180 -0
  427. package/dist/surface/primitives.js +339 -0
  428. package/dist/surface/primitives.js.map +1 -0
  429. package/dist/surface/renderer.d.ts +96 -0
  430. package/dist/surface/renderer.js +190 -0
  431. package/dist/surface/renderer.js.map +1 -0
  432. package/dist/surface/schemas.d.ts +181 -0
  433. package/dist/surface/schemas.js +142 -0
  434. package/dist/surface/schemas.js.map +1 -0
  435. package/dist/surface/transforms.d.ts +144 -0
  436. package/dist/surface/transforms.js +120 -0
  437. package/dist/surface/transforms.js.map +1 -0
  438. package/dist/surface/types.d.ts +160 -0
  439. package/dist/surface/types.js +51 -0
  440. package/dist/surface/types.js.map +1 -0
  441. package/dist/surface/validation.d.ts +123 -0
  442. package/dist/surface/validation.js +147 -0
  443. package/dist/surface/validation.js.map +1 -0
  444. package/dist/validator.d.ts +55 -0
  445. package/dist/validator.js +100 -0
  446. package/dist/validator.js.map +1 -0
  447. package/package.json +106 -3
@@ -0,0 +1,349 @@
1
+ /**
2
+ * Entity Store
3
+ *
4
+ * Uniform CRUD and query interface backed by connectors.
5
+ * The store handles validation and delegates persistence to connectors.
6
+ *
7
+ * @module @pwfabric/runtime/entity/store
8
+ */
9
+ import { aggregateThrough } from './aggregate.js';
10
+ // ============================================================
11
+ // DEFAULT ENTITY STORE
12
+ // ============================================================
13
+ /**
14
+ * Default implementation of EntityStore.
15
+ * Validates through the registry and delegates persistence to connectors.
16
+ *
17
+ * Accepts an optional SurfaceEventBus. When provided, successful
18
+ * CRUD operations emit entity:created / entity:updated / entity:deleted events on
19
+ * the bus so that the rest of the surface can react declaratively.
20
+ *
21
+ * The bus is surface-scoped — the caller injects the bus for a
22
+ * specific surface, keeping the store surface-aware without making it globally coupled.
23
+ */
24
+ /**
25
+ * The id of a record a connector just created. A record service may answer
26
+ * with the record itself (`{ id, … }`) or wrap it (`{ data: { id, … } }`, the
27
+ * shape the data protocol specifies); both are read.
28
+ */
29
+ function createdIdOf(body) {
30
+ const own = body?.['id'];
31
+ if (typeof own === 'string' || typeof own === 'number')
32
+ return String(own);
33
+ const inner = body?.['data'];
34
+ if (inner && typeof inner === 'object' && !Array.isArray(inner)) {
35
+ const id = inner['id'];
36
+ if (typeof id === 'string' || typeof id === 'number')
37
+ return String(id);
38
+ }
39
+ return '';
40
+ }
41
+ export class DefaultEntityStore {
42
+ registry;
43
+ connectors;
44
+ eventBus;
45
+ constructor(registry, connectors, eventBus) {
46
+ this.registry = registry;
47
+ this.connectors = connectors;
48
+ this.eventBus = eventBus ?? undefined;
49
+ }
50
+ async create(entityType, data) {
51
+ // Validate entity type exists
52
+ if (!this.registry.has(entityType)) {
53
+ return {
54
+ success: false,
55
+ error: {
56
+ type: 'not_found',
57
+ message: `Entity type '${entityType}' is not registered`,
58
+ },
59
+ };
60
+ }
61
+ // Validate data against schema
62
+ const validation = this.registry.validate(entityType, data);
63
+ if (!validation.valid) {
64
+ return {
65
+ success: false,
66
+ error: {
67
+ type: 'validation',
68
+ message: 'Validation failed',
69
+ details: validation.errors,
70
+ },
71
+ };
72
+ }
73
+ // Resolve connector
74
+ const connector = this.connectors.resolve(entityType);
75
+ if (!connector) {
76
+ return {
77
+ success: false,
78
+ error: {
79
+ type: 'connector',
80
+ message: `No connector found for entity type '${entityType}'`,
81
+ },
82
+ };
83
+ }
84
+ // Delegate to connector
85
+ const result = await connector.create(entityType, validation.data);
86
+ if (!result.success) {
87
+ return {
88
+ success: false,
89
+ error: {
90
+ type: 'connector',
91
+ message: result.error,
92
+ },
93
+ };
94
+ }
95
+ const mutationResult = {
96
+ success: true,
97
+ data: result.data,
98
+ id: createdIdOf(result.data),
99
+ };
100
+ // emit entity:created on the surface-scoped bus
101
+ if (this.eventBus) {
102
+ this.eventBus.emit({
103
+ type: 'entity:created',
104
+ surfaceId: 'system',
105
+ payload: {
106
+ entityType,
107
+ instanceId: mutationResult.id,
108
+ data: mutationResult.data,
109
+ timestamp: Date.now(),
110
+ },
111
+ timestamp: Date.now(),
112
+ });
113
+ }
114
+ return mutationResult;
115
+ }
116
+ async read(entityType, instanceId) {
117
+ // Validate entity type exists
118
+ if (!this.registry.has(entityType)) {
119
+ return {
120
+ success: false,
121
+ error: {
122
+ type: 'not_found',
123
+ message: `Entity type '${entityType}' is not registered`,
124
+ },
125
+ };
126
+ }
127
+ // Resolve connector
128
+ const connector = this.connectors.resolve(entityType);
129
+ if (!connector) {
130
+ return {
131
+ success: false,
132
+ error: {
133
+ type: 'connector',
134
+ message: `No connector found for entity type '${entityType}'`,
135
+ },
136
+ };
137
+ }
138
+ // Delegate to connector
139
+ const result = await connector.read(entityType, instanceId);
140
+ if (!result.success) {
141
+ return {
142
+ success: false,
143
+ error: {
144
+ type: 'not_found',
145
+ message: result.error,
146
+ },
147
+ };
148
+ }
149
+ return {
150
+ success: true,
151
+ data: result.data,
152
+ };
153
+ }
154
+ async update(entityType, instanceId, data) {
155
+ // Validate entity type exists
156
+ if (!this.registry.has(entityType)) {
157
+ return {
158
+ success: false,
159
+ error: {
160
+ type: 'not_found',
161
+ message: `Entity type '${entityType}' is not registered`,
162
+ },
163
+ };
164
+ }
165
+ // Read existing record to merge with updates for validation
166
+ const connector = this.connectors.resolve(entityType);
167
+ if (!connector) {
168
+ return {
169
+ success: false,
170
+ error: {
171
+ type: 'connector',
172
+ message: `No connector found for entity type '${entityType}'`,
173
+ },
174
+ };
175
+ }
176
+ const existing = await connector.read(entityType, instanceId);
177
+ if (!existing.success) {
178
+ return {
179
+ success: false,
180
+ error: {
181
+ type: 'not_found',
182
+ message: existing.error,
183
+ },
184
+ };
185
+ }
186
+ // Merge existing data with updates for full validation
187
+ const merged = { ...existing.data, ...data };
188
+ const validation = this.registry.validate(entityType, merged);
189
+ if (!validation.valid) {
190
+ return {
191
+ success: false,
192
+ error: {
193
+ type: 'validation',
194
+ message: 'Validation failed',
195
+ details: validation.errors,
196
+ },
197
+ };
198
+ }
199
+ // Delegate to connector
200
+ const result = await connector.update(entityType, instanceId, data);
201
+ if (!result.success) {
202
+ return {
203
+ success: false,
204
+ error: {
205
+ type: 'connector',
206
+ message: result.error,
207
+ },
208
+ };
209
+ }
210
+ const updateResult = {
211
+ success: true,
212
+ data: result.data,
213
+ id: instanceId,
214
+ };
215
+ // emit entity:updated on the surface-scoped bus
216
+ if (this.eventBus) {
217
+ this.eventBus.emit({
218
+ type: 'entity:updated',
219
+ surfaceId: 'system',
220
+ payload: {
221
+ entityType,
222
+ instanceId,
223
+ data: updateResult.data,
224
+ changeset: data,
225
+ timestamp: Date.now(),
226
+ },
227
+ timestamp: Date.now(),
228
+ });
229
+ }
230
+ return updateResult;
231
+ }
232
+ async delete(entityType, instanceId) {
233
+ // Validate entity type exists
234
+ if (!this.registry.has(entityType)) {
235
+ return {
236
+ success: false,
237
+ error: {
238
+ type: 'not_found',
239
+ message: `Entity type '${entityType}' is not registered`,
240
+ },
241
+ };
242
+ }
243
+ // Resolve connector
244
+ const connector = this.connectors.resolve(entityType);
245
+ if (!connector) {
246
+ return {
247
+ success: false,
248
+ error: {
249
+ type: 'connector',
250
+ message: `No connector found for entity type '${entityType}'`,
251
+ },
252
+ };
253
+ }
254
+ // Delegate to connector
255
+ const result = await connector.delete(entityType, instanceId);
256
+ if (!result.success) {
257
+ return {
258
+ success: false,
259
+ error: {
260
+ type: 'not_found',
261
+ message: result.error,
262
+ },
263
+ };
264
+ }
265
+ const deleteResult = {
266
+ success: true,
267
+ data: result.data,
268
+ id: instanceId,
269
+ };
270
+ // emit entity:deleted on the surface-scoped bus
271
+ if (this.eventBus) {
272
+ this.eventBus.emit({
273
+ type: 'entity:deleted',
274
+ surfaceId: 'system',
275
+ payload: {
276
+ entityType,
277
+ instanceId,
278
+ timestamp: Date.now(),
279
+ },
280
+ timestamp: Date.now(),
281
+ });
282
+ }
283
+ return deleteResult;
284
+ }
285
+ async query(entityType, query) {
286
+ // Validate entity type exists
287
+ if (!this.registry.has(entityType)) {
288
+ return {
289
+ items: [],
290
+ total: 0,
291
+ offset: 0,
292
+ limit: query.pagination?.limit ?? 50,
293
+ hasMore: false,
294
+ };
295
+ }
296
+ // Resolve connector
297
+ const connector = this.connectors.resolve(entityType);
298
+ if (!connector) {
299
+ return {
300
+ items: [],
301
+ total: 0,
302
+ offset: 0,
303
+ limit: query.pagination?.limit ?? 50,
304
+ hasMore: false,
305
+ };
306
+ }
307
+ // Delegate to connector
308
+ const result = await connector.query(entityType, query);
309
+ if (!result.success) {
310
+ return {
311
+ items: [],
312
+ total: 0,
313
+ offset: 0,
314
+ limit: query.pagination?.limit ?? 50,
315
+ hasMore: false,
316
+ };
317
+ }
318
+ return result.result;
319
+ }
320
+ async aggregate(entityType, aggregate) {
321
+ // NOT the same as query. An empty list is an honest answer to "could not
322
+ // list"; `{ value: 0 }` is not an honest answer to "could not count" —
323
+ // a 403 would read as "0 people are coming". Reject, and the renderer
324
+ // binds `fallback` and `__errors.<id>` like any failed source.
325
+ if (!this.registry.has(entityType)) {
326
+ throw new Error(`Entity type '${String(entityType)}' is not registered`);
327
+ }
328
+ const connector = this.connectors.resolve(entityType);
329
+ if (!connector)
330
+ throw new Error(`No connector for entity type '${String(entityType)}'`);
331
+ const result = await aggregateThrough(connector, entityType, aggregate);
332
+ if (!result.success)
333
+ throw new Error(result.error);
334
+ return result.result;
335
+ }
336
+ }
337
+ // ============================================================
338
+ // FACTORY FUNCTION
339
+ // ============================================================
340
+ /**
341
+ * Create an entity store.
342
+ *
343
+ * Pass an optional `eventBus` to enable surface-scoped event
344
+ * emission on successful CRUD operations (entity:created, entity:updated, entity:deleted).
345
+ */
346
+ export function createEntityStore(registry, connectors, eventBus) {
347
+ return new DefaultEntityStore(registry, connectors, eventBus);
348
+ }
349
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/entity/store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Entity Store\n *\n * Uniform CRUD and query interface backed by connectors.\n * The store handles validation and delegates persistence to connectors.\n *\n * @module @pwfabric/runtime/entity/store\n */\n\nimport type {\n EntityTypeId,\n EntityInstanceId,\n EntityQuery,\n EntityQueryResult,\n EntityMutationResult,\n EntityReadResult,\n EntityAggregate,\n EntityAggregateResult,\n} from './types.js'\nimport { aggregateThrough } from './aggregate.js'\nimport type { EntityRegistry } from './registry.js'\nimport type { ConnectorRegistry } from './connector.js'\nimport type { SurfaceEventBus } from '@pwfabric/contracts'\n\n// ============================================================\n// ENTITY STORE INTERFACE\n// ============================================================\n\n/**\n * Entity store interface for CRUD operations\n */\nexport interface EntityStore {\n /**\n * Create a new entity instance\n */\n create(entityType: EntityTypeId, data: Record<string, unknown>): Promise<EntityMutationResult>\n\n /**\n * Read a single entity instance\n */\n read(entityType: EntityTypeId, instanceId: EntityInstanceId): Promise<EntityReadResult>\n\n /**\n * Update an existing entity instance\n */\n update(\n entityType: EntityTypeId,\n instanceId: EntityInstanceId,\n data: Record<string, unknown>\n ): Promise<EntityMutationResult>\n\n /**\n * Delete an entity instance\n */\n delete(entityType: EntityTypeId, instanceId: EntityInstanceId): Promise<EntityMutationResult>\n\n /**\n * Query entity instances\n */\n query(entityType: EntityTypeId, query: EntityQuery): Promise<EntityQueryResult>\n\n /**\n * One number over the collection. Server-side when the connector\n * can; otherwise the connector's rows are reduced in memory. REJECTS when\n * the number cannot be served — unlike `query`, whose honest failure is an\n * empty list, a counter's `0` would be a lie.\n *\n * OPTIONAL so a host-written `EntityStore` keeps compiling; the facade\n * lists and reduces through `query` when a store has none.\n */\n aggregate?(entityType: EntityTypeId, aggregate: EntityAggregate): Promise<EntityAggregateResult>\n}\n\n// ============================================================\n// DEFAULT ENTITY STORE\n// ============================================================\n\n/**\n * Default implementation of EntityStore.\n * Validates through the registry and delegates persistence to connectors.\n *\n * Accepts an optional SurfaceEventBus. When provided, successful\n * CRUD operations emit entity:created / entity:updated / entity:deleted events on\n * the bus so that the rest of the surface can react declaratively.\n *\n * The bus is surface-scoped — the caller injects the bus for a\n * specific surface, keeping the store surface-aware without making it globally coupled.\n */\n/**\n * The id of a record a connector just created. A record service may answer\n * with the record itself (`{ id, … }`) or wrap it (`{ data: { id, … } }`, the\n * shape the data protocol specifies); both are read.\n */\nfunction createdIdOf(body: Record<string, unknown> | undefined): EntityInstanceId {\n const own = body?.['id']\n if (typeof own === 'string' || typeof own === 'number') return String(own) as EntityInstanceId\n const inner = body?.['data']\n if (inner && typeof inner === 'object' && !Array.isArray(inner)) {\n const id = (inner as Record<string, unknown>)['id']\n if (typeof id === 'string' || typeof id === 'number') return String(id) as EntityInstanceId\n }\n return '' as EntityInstanceId\n}\n\nexport class DefaultEntityStore implements EntityStore {\n private readonly registry: EntityRegistry\n private readonly connectors: ConnectorRegistry\n private readonly eventBus: SurfaceEventBus | undefined\n\n constructor(registry: EntityRegistry, connectors: ConnectorRegistry, eventBus?: SurfaceEventBus) {\n this.registry = registry\n this.connectors = connectors\n this.eventBus = eventBus ?? undefined\n }\n\n async create(\n entityType: EntityTypeId,\n data: Record<string, unknown>\n ): Promise<EntityMutationResult> {\n // Validate entity type exists\n if (!this.registry.has(entityType)) {\n return {\n success: false,\n error: {\n type: 'not_found',\n message: `Entity type '${entityType}' is not registered`,\n },\n }\n }\n\n // Validate data against schema\n const validation = this.registry.validate(entityType, data)\n if (!validation.valid) {\n return {\n success: false,\n error: {\n type: 'validation',\n message: 'Validation failed',\n details: validation.errors,\n },\n }\n }\n\n // Resolve connector\n const connector = this.connectors.resolve(entityType)\n if (!connector) {\n return {\n success: false,\n error: {\n type: 'connector',\n message: `No connector found for entity type '${entityType}'`,\n },\n }\n }\n\n // Delegate to connector\n const result = await connector.create(entityType, validation.data)\n if (!result.success) {\n return {\n success: false,\n error: {\n type: 'connector',\n message: result.error,\n },\n }\n }\n\n const mutationResult: EntityMutationResult = {\n success: true,\n data: result.data,\n id: createdIdOf(result.data),\n }\n\n // emit entity:created on the surface-scoped bus\n if (this.eventBus) {\n this.eventBus.emit({\n type: 'entity:created',\n surfaceId: 'system',\n payload: {\n entityType,\n instanceId: mutationResult.id,\n data: mutationResult.data,\n timestamp: Date.now(),\n },\n timestamp: Date.now(),\n })\n }\n\n return mutationResult\n }\n\n async read(entityType: EntityTypeId, instanceId: EntityInstanceId): Promise<EntityReadResult> {\n // Validate entity type exists\n if (!this.registry.has(entityType)) {\n return {\n success: false,\n error: {\n type: 'not_found',\n message: `Entity type '${entityType}' is not registered`,\n },\n }\n }\n\n // Resolve connector\n const connector = this.connectors.resolve(entityType)\n if (!connector) {\n return {\n success: false,\n error: {\n type: 'connector',\n message: `No connector found for entity type '${entityType}'`,\n },\n }\n }\n\n // Delegate to connector\n const result = await connector.read(entityType, instanceId)\n if (!result.success) {\n return {\n success: false,\n error: {\n type: 'not_found',\n message: result.error,\n },\n }\n }\n\n return {\n success: true,\n data: result.data,\n }\n }\n\n async update(\n entityType: EntityTypeId,\n instanceId: EntityInstanceId,\n data: Record<string, unknown>\n ): Promise<EntityMutationResult> {\n // Validate entity type exists\n if (!this.registry.has(entityType)) {\n return {\n success: false,\n error: {\n type: 'not_found',\n message: `Entity type '${entityType}' is not registered`,\n },\n }\n }\n\n // Read existing record to merge with updates for validation\n const connector = this.connectors.resolve(entityType)\n if (!connector) {\n return {\n success: false,\n error: {\n type: 'connector',\n message: `No connector found for entity type '${entityType}'`,\n },\n }\n }\n\n const existing = await connector.read(entityType, instanceId)\n if (!existing.success) {\n return {\n success: false,\n error: {\n type: 'not_found',\n message: existing.error,\n },\n }\n }\n\n // Merge existing data with updates for full validation\n const merged = { ...existing.data, ...data }\n const validation = this.registry.validate(entityType, merged)\n if (!validation.valid) {\n return {\n success: false,\n error: {\n type: 'validation',\n message: 'Validation failed',\n details: validation.errors,\n },\n }\n }\n\n // Delegate to connector\n const result = await connector.update(entityType, instanceId, data)\n if (!result.success) {\n return {\n success: false,\n error: {\n type: 'connector',\n message: result.error,\n },\n }\n }\n\n const updateResult: EntityMutationResult = {\n success: true,\n data: result.data,\n id: instanceId,\n }\n\n // emit entity:updated on the surface-scoped bus\n if (this.eventBus) {\n this.eventBus.emit({\n type: 'entity:updated',\n surfaceId: 'system',\n payload: {\n entityType,\n instanceId,\n data: updateResult.data,\n changeset: data,\n timestamp: Date.now(),\n },\n timestamp: Date.now(),\n })\n }\n\n return updateResult\n }\n\n async delete(\n entityType: EntityTypeId,\n instanceId: EntityInstanceId\n ): Promise<EntityMutationResult> {\n // Validate entity type exists\n if (!this.registry.has(entityType)) {\n return {\n success: false,\n error: {\n type: 'not_found',\n message: `Entity type '${entityType}' is not registered`,\n },\n }\n }\n\n // Resolve connector\n const connector = this.connectors.resolve(entityType)\n if (!connector) {\n return {\n success: false,\n error: {\n type: 'connector',\n message: `No connector found for entity type '${entityType}'`,\n },\n }\n }\n\n // Delegate to connector\n const result = await connector.delete(entityType, instanceId)\n if (!result.success) {\n return {\n success: false,\n error: {\n type: 'not_found',\n message: result.error,\n },\n }\n }\n\n const deleteResult: EntityMutationResult = {\n success: true,\n data: result.data,\n id: instanceId,\n }\n\n // emit entity:deleted on the surface-scoped bus\n if (this.eventBus) {\n this.eventBus.emit({\n type: 'entity:deleted',\n surfaceId: 'system',\n payload: {\n entityType,\n instanceId,\n timestamp: Date.now(),\n },\n timestamp: Date.now(),\n })\n }\n\n return deleteResult\n }\n\n async query(entityType: EntityTypeId, query: EntityQuery): Promise<EntityQueryResult> {\n // Validate entity type exists\n if (!this.registry.has(entityType)) {\n return {\n items: [],\n total: 0,\n offset: 0,\n limit: query.pagination?.limit ?? 50,\n hasMore: false,\n }\n }\n\n // Resolve connector\n const connector = this.connectors.resolve(entityType)\n if (!connector) {\n return {\n items: [],\n total: 0,\n offset: 0,\n limit: query.pagination?.limit ?? 50,\n hasMore: false,\n }\n }\n\n // Delegate to connector\n const result = await connector.query(entityType, query)\n if (!result.success) {\n return {\n items: [],\n total: 0,\n offset: 0,\n limit: query.pagination?.limit ?? 50,\n hasMore: false,\n }\n }\n\n return result.result\n }\n\n async aggregate(entityType: EntityTypeId, aggregate: EntityAggregate): Promise<EntityAggregateResult> {\n // NOT the same as query. An empty list is an honest answer to \"could not\n // list\"; `{ value: 0 }` is not an honest answer to \"could not count\" —\n // a 403 would read as \"0 people are coming\". Reject, and the renderer\n // binds `fallback` and `__errors.<id>` like any failed source.\n if (!this.registry.has(entityType)) {\n throw new Error(`Entity type '${String(entityType)}' is not registered`)\n }\n const connector = this.connectors.resolve(entityType)\n if (!connector) throw new Error(`No connector for entity type '${String(entityType)}'`)\n const result = await aggregateThrough(connector, entityType, aggregate)\n if (!result.success) throw new Error(result.error)\n return result.result\n }\n}\n\n// ============================================================\n// FACTORY FUNCTION\n// ============================================================\n\n/**\n * Create an entity store.\n *\n * Pass an optional `eventBus` to enable surface-scoped event\n * emission on successful CRUD operations (entity:created, entity:updated, entity:deleted).\n */\nexport function createEntityStore(\n registry: EntityRegistry,\n connectors: ConnectorRegistry,\n eventBus?: SurfaceEventBus\n): EntityStore {\n return new DefaultEntityStore(registry, connectors, eventBus)\n}\n"]}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Entity System Types
3
+ *
4
+ * Entity system type definitions for schema-based entity types,
5
+ * CRUD operations, queries, and validation.
6
+ *
7
+ * @module @pwfabric/runtime/entity/types
8
+ */
9
+ import type { z } from 'zod';
10
+ /**
11
+ * Branded string type for entity type identifiers
12
+ */
13
+ export type EntityTypeId = string & {
14
+ readonly __brand: 'EntityTypeId';
15
+ };
16
+ /**
17
+ * Branded string type for entity instance identifiers
18
+ */
19
+ export type EntityInstanceId = string & {
20
+ readonly __brand: 'EntityInstanceId';
21
+ };
22
+ /**
23
+ * Supported field types for entity definitions
24
+ */
25
+ export type EntityFieldType = 'string' | 'number' | 'boolean' | 'date' | 'datetime' | 'enum' | 'json' | 'reference';
26
+ /**
27
+ * Definition of a single field within an entity
28
+ */
29
+ export interface EntityFieldDefinition {
30
+ readonly name: string;
31
+ readonly type: EntityFieldType;
32
+ readonly required: boolean;
33
+ readonly unique?: boolean;
34
+ readonly defaultValue?: unknown;
35
+ readonly enumValues?: readonly string[];
36
+ readonly referenceTarget?: EntityTypeId;
37
+ readonly validation?: z.ZodType;
38
+ readonly label?: string;
39
+ readonly description?: string;
40
+ }
41
+ /**
42
+ * Supported relation types between entities
43
+ */
44
+ export type EntityRelationType = 'has-one' | 'has-many' | 'belongs-to' | 'many-to-many';
45
+ /**
46
+ * Definition of a relation between entity types
47
+ */
48
+ export interface EntityRelationDefinition {
49
+ readonly name: string;
50
+ readonly type: EntityRelationType;
51
+ readonly target: EntityTypeId;
52
+ readonly foreignKey?: string;
53
+ readonly through?: EntityTypeId;
54
+ readonly cascade?: 'none' | 'delete' | 'nullify';
55
+ }
56
+ /**
57
+ * Complete definition of an entity type including fields, relations, and schema
58
+ */
59
+ export interface EntityDefinition {
60
+ readonly id: EntityTypeId;
61
+ readonly name: string;
62
+ readonly description?: string;
63
+ readonly fields: readonly EntityFieldDefinition[];
64
+ readonly relations: readonly EntityRelationDefinition[];
65
+ readonly primaryKey: string;
66
+ readonly timestamps?: boolean;
67
+ readonly softDelete?: boolean;
68
+ readonly schema: z.ZodObject<z.ZodRawShape>;
69
+ }
70
+ /**
71
+ * Entity query specification with optional filter, sort, and pagination
72
+ */
73
+ export interface EntityQuery {
74
+ readonly filter?: EntityFilter;
75
+ readonly sort?: readonly EntitySortField[];
76
+ readonly pagination?: EntityPagination;
77
+ readonly include?: readonly string[];
78
+ }
79
+ /**
80
+ * Filter condition for entity queries
81
+ */
82
+ export interface EntityFilter {
83
+ readonly field: string;
84
+ readonly operator: 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'contains' | 'startsWith';
85
+ readonly value: unknown;
86
+ readonly and?: readonly EntityFilter[];
87
+ readonly or?: readonly EntityFilter[];
88
+ }
89
+ /**
90
+ * Sort field specification
91
+ */
92
+ export interface EntitySortField {
93
+ readonly field: string;
94
+ readonly direction: 'asc' | 'desc';
95
+ }
96
+ /**
97
+ * Pagination parameters
98
+ */
99
+ export interface EntityPagination {
100
+ readonly offset: number;
101
+ readonly limit: number;
102
+ }
103
+ /** One number over a collection: `count` needs no field, the rest reduce `field`. */
104
+ export type EntityAggregateFn = 'count' | 'sum' | 'avg';
105
+ /**
106
+ * An aggregate request — the source-level `aggregate` key. `filter`
107
+ * narrows the rows first, in the `EntityQuery.filter` shape.
108
+ */
109
+ export interface EntityAggregate {
110
+ readonly fn: EntityAggregateFn;
111
+ readonly field?: string;
112
+ readonly filter?: EntityFilter;
113
+ }
114
+ /**
115
+ * What an aggregate answers: `value` is the number (`null` when a numeric
116
+ * fn found nothing to reduce), `count` the rows the filter kept.
117
+ */
118
+ export interface EntityAggregateResult {
119
+ readonly fn: EntityAggregateFn;
120
+ readonly field?: string;
121
+ readonly value: number | null;
122
+ readonly count: number;
123
+ }
124
+ /**
125
+ * Result of a paginated entity query
126
+ */
127
+ export interface EntityQueryResult<T = Record<string, unknown>> {
128
+ readonly items: readonly T[];
129
+ readonly total: number;
130
+ readonly offset: number;
131
+ readonly limit: number;
132
+ readonly hasMore: boolean;
133
+ }
134
+ /**
135
+ * Result of a create or update mutation
136
+ */
137
+ export type EntityMutationResult = {
138
+ readonly success: true;
139
+ readonly data: Record<string, unknown>;
140
+ readonly id: EntityInstanceId;
141
+ } | {
142
+ readonly success: false;
143
+ readonly error: EntityOperationError;
144
+ };
145
+ /**
146
+ * Result of a read operation
147
+ */
148
+ export type EntityReadResult = {
149
+ readonly success: true;
150
+ readonly data: Record<string, unknown>;
151
+ } | {
152
+ readonly success: false;
153
+ readonly error: EntityOperationError;
154
+ };
155
+ /**
156
+ * Error descriptor for entity operations
157
+ */
158
+ export interface EntityOperationError {
159
+ readonly type: 'not_found' | 'validation' | 'conflict' | 'connector' | 'unauthorized' | 'unknown';
160
+ readonly message: string;
161
+ readonly details?: unknown;
162
+ }
163
+ /**
164
+ * Result of entity validation (discriminated union)
165
+ */
166
+ export type EntityValidationResult = {
167
+ readonly valid: true;
168
+ readonly data: Record<string, unknown>;
169
+ } | {
170
+ readonly valid: false;
171
+ readonly errors: readonly EntityValidationError[];
172
+ };
173
+ /**
174
+ * Single field validation error
175
+ */
176
+ export interface EntityValidationError {
177
+ readonly field: string;
178
+ readonly message: string;
179
+ readonly code: string;
180
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Entity System Types
3
+ *
4
+ * Entity system type definitions for schema-based entity types,
5
+ * CRUD operations, queries, and validation.
6
+ *
7
+ * @module @pwfabric/runtime/entity/types
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/entity/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG","sourcesContent":["/**\n * Entity System Types\n *\n * Entity system type definitions for schema-based entity types,\n * CRUD operations, queries, and validation.\n *\n * @module @pwfabric/runtime/entity/types\n */\n\nimport type { z } from 'zod'\n\n// ============================================================\n// BRANDED IDENTIFIERS\n// ============================================================\n\n/**\n * Branded string type for entity type identifiers\n */\nexport type EntityTypeId = string & { readonly __brand: 'EntityTypeId' }\n\n/**\n * Branded string type for entity instance identifiers\n */\nexport type EntityInstanceId = string & { readonly __brand: 'EntityInstanceId' }\n\n// ============================================================\n// ENTITY FIELD DEFINITIONS\n// ============================================================\n\n/**\n * Supported field types for entity definitions\n */\nexport type EntityFieldType =\n | 'string'\n | 'number'\n | 'boolean'\n | 'date'\n | 'datetime'\n | 'enum'\n | 'json'\n | 'reference'\n\n/**\n * Definition of a single field within an entity\n */\nexport interface EntityFieldDefinition {\n readonly name: string\n readonly type: EntityFieldType\n readonly required: boolean\n readonly unique?: boolean\n readonly defaultValue?: unknown\n readonly enumValues?: readonly string[]\n readonly referenceTarget?: EntityTypeId\n readonly validation?: z.ZodType\n readonly label?: string\n readonly description?: string\n}\n\n// ============================================================\n// ENTITY RELATION DEFINITIONS\n// ============================================================\n\n/**\n * Supported relation types between entities\n */\nexport type EntityRelationType = 'has-one' | 'has-many' | 'belongs-to' | 'many-to-many'\n\n/**\n * Definition of a relation between entity types\n */\nexport interface EntityRelationDefinition {\n readonly name: string\n readonly type: EntityRelationType\n readonly target: EntityTypeId\n readonly foreignKey?: string\n readonly through?: EntityTypeId\n readonly cascade?: 'none' | 'delete' | 'nullify'\n}\n\n// ============================================================\n// ENTITY DEFINITION\n// ============================================================\n\n/**\n * Complete definition of an entity type including fields, relations, and schema\n */\nexport interface EntityDefinition {\n readonly id: EntityTypeId\n readonly name: string\n readonly description?: string\n readonly fields: readonly EntityFieldDefinition[]\n readonly relations: readonly EntityRelationDefinition[]\n readonly primaryKey: string\n readonly timestamps?: boolean\n readonly softDelete?: boolean\n readonly schema: z.ZodObject<z.ZodRawShape>\n}\n\n// ============================================================\n// QUERY TYPES\n// ============================================================\n\n/**\n * Entity query specification with optional filter, sort, and pagination\n */\nexport interface EntityQuery {\n readonly filter?: EntityFilter\n readonly sort?: readonly EntitySortField[]\n readonly pagination?: EntityPagination\n readonly include?: readonly string[]\n}\n\n/**\n * Filter condition for entity queries\n */\nexport interface EntityFilter {\n readonly field: string\n readonly operator: 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'contains' | 'startsWith'\n readonly value: unknown\n readonly and?: readonly EntityFilter[]\n readonly or?: readonly EntityFilter[]\n}\n\n/**\n * Sort field specification\n */\nexport interface EntitySortField {\n readonly field: string\n readonly direction: 'asc' | 'desc'\n}\n\n/**\n * Pagination parameters\n */\nexport interface EntityPagination {\n readonly offset: number\n readonly limit: number\n}\n\n/** One number over a collection: `count` needs no field, the rest reduce `field`. */\nexport type EntityAggregateFn = 'count' | 'sum' | 'avg'\n\n/**\n * An aggregate request — the source-level `aggregate` key. `filter`\n * narrows the rows first, in the `EntityQuery.filter` shape.\n */\nexport interface EntityAggregate {\n readonly fn: EntityAggregateFn\n readonly field?: string\n readonly filter?: EntityFilter\n}\n\n/**\n * What an aggregate answers: `value` is the number (`null` when a numeric\n * fn found nothing to reduce), `count` the rows the filter kept.\n */\nexport interface EntityAggregateResult {\n readonly fn: EntityAggregateFn\n readonly field?: string\n readonly value: number | null\n readonly count: number\n}\n\n/**\n * Result of a paginated entity query\n */\nexport interface EntityQueryResult<T = Record<string, unknown>> {\n readonly items: readonly T[]\n readonly total: number\n readonly offset: number\n readonly limit: number\n readonly hasMore: boolean\n}\n\n// ============================================================\n// OPERATION RESULTS (DISCRIMINATED UNIONS)\n// ============================================================\n\n/**\n * Result of a create or update mutation\n */\nexport type EntityMutationResult =\n | {\n readonly success: true\n readonly data: Record<string, unknown>\n readonly id: EntityInstanceId\n }\n | { readonly success: false; readonly error: EntityOperationError }\n\n/**\n * Result of a read operation\n */\nexport type EntityReadResult =\n | { readonly success: true; readonly data: Record<string, unknown> }\n | { readonly success: false; readonly error: EntityOperationError }\n\n/**\n * Error descriptor for entity operations\n */\nexport interface EntityOperationError {\n readonly type: 'not_found' | 'validation' | 'conflict' | 'connector' | 'unauthorized' | 'unknown'\n readonly message: string\n readonly details?: unknown\n}\n\n// ============================================================\n// VALIDATION TYPES\n// ============================================================\n\n/**\n * Result of entity validation (discriminated union)\n */\nexport type EntityValidationResult =\n | { readonly valid: true; readonly data: Record<string, unknown> }\n | { readonly valid: false; readonly errors: readonly EntityValidationError[] }\n\n/**\n * Single field validation error\n */\nexport interface EntityValidationError {\n readonly field: string\n readonly message: string\n readonly code: string\n}\n"]}