@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 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/state/manager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAE/C,+DAA+D;AAC/D,gCAAgC;AAChC,+DAA+D;AAE/D;;;GAGG;AACH,MAAM,OAAO,0BAA0B;IACpB,MAAM,GAAG,IAAI,GAAG,EAA+B,CAAA;IAC/C,aAAa,CAAkB;IAEhD,YAAY,gBAAkC,EAAE;QAC9C,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA;IACpC,CAAC;IAED,WAAW,CAAI,SAAiB,EAAE,YAAe;QAC/C,wEAAwE;QACxE,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,2CAA2C,SAAS,EAAE,CAAC,CAAA;QACzE,CAAC;QAED,+DAA+D;QAC/D,MAAM,WAAW,GAAG,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAA;QAC5D,MAAM,KAAK,GAAG,IAAI,kBAAkB,CAAU,WAAW,EAAE,IAAI,CAAC,aAAa,CAAC,CAAA;QAE9E,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;QAEjC,OAAO,KAAsB,CAAA;IAC/B,CAAC;IAED,QAAQ,CAAI,SAAiB;QAC3B,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAA8B,CAAA;IAChE,CAAC;IAED,QAAQ,CAAC,SAAiB;QACxB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IACnC,CAAC;IAED,YAAY,CAAC,SAAiB;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QACxC,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,CAAC,KAAK,EAAE,CAAA;YACb,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAC/B,CAAC;IACH,CAAC;IAED,UAAU;QACR,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACzC,KAAK,CAAC,KAAK,EAAE,CAAA;QACf,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;IACrB,CAAC;IAED,aAAa;QACX,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA;IACvC,CAAC;IAED;;;OAGG;IACH,gBAAgB,CAAI,SAAiB,EAAE,YAAgB;QACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAI,SAAS,CAAC,CAAA;QAC5C,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,QAAQ,CAAA;QACjB,CAAC;QAED,OAAO,IAAI,CAAC,WAAW,CAAI,SAAS,EAAE,YAAY,IAAK,EAAQ,CAAC,CAAA;IAClE,CAAC;IAEO,qBAAqB,CAAI,YAAe;QAC9C,6DAA6D;QAC7D,IAAI,YAAY,KAAK,IAAI,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YAC9F,OAAO,YAAuC,CAAA;QAChD,CAAC;QAED,mCAAmC;QACnC,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,CAAA;IAChC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAyB;IACjE,OAAO,IAAI,0BAA0B,CAAC,MAAM,CAAC,CAAA;AAC/C,CAAC","sourcesContent":["/**\n * Surface State Manager\n *\n * Manager for surface-scoped state stores\n *\n * @module @pwfabric/runtime/state/manager\n */\n\nimport type { SurfaceStateManager, StateStore, StateStoreConfig } from './types.js'\nimport { InMemoryStateStore } from './store.js'\n\n// ============================================================\n// DEFAULT SURFACE STATE MANAGER\n// ============================================================\n\n/**\n * Default implementation of SurfaceStateManager\n * Manages multiple state stores, one per surface\n */\nexport class DefaultSurfaceStateManager implements SurfaceStateManager {\n private readonly stores = new Map<string, StateStore<unknown>>()\n private readonly defaultConfig: StateStoreConfig\n\n constructor(defaultConfig: StateStoreConfig = {}) {\n this.defaultConfig = defaultConfig\n }\n\n createStore<T>(surfaceId: string, initialState: T): StateStore<T> {\n // If store already exists, throw error to prevent accidental overwrites\n if (this.stores.has(surfaceId)) {\n throw new Error(`State store already exists for surface: ${surfaceId}`)\n }\n\n // Convert single value initialState to object format if needed\n const stateObject = this.normalizeInitialState(initialState)\n const store = new InMemoryStateStore<unknown>(stateObject, this.defaultConfig)\n\n this.stores.set(surfaceId, store)\n\n return store as StateStore<T>\n }\n\n getStore<T>(surfaceId: string): StateStore<T> | undefined {\n return this.stores.get(surfaceId) as StateStore<T> | undefined\n }\n\n hasStore(surfaceId: string): boolean {\n return this.stores.has(surfaceId)\n }\n\n destroyStore(surfaceId: string): void {\n const store = this.stores.get(surfaceId)\n if (store) {\n store.clear()\n this.stores.delete(surfaceId)\n }\n }\n\n destroyAll(): void {\n for (const store of this.stores.values()) {\n store.clear()\n }\n this.stores.clear()\n }\n\n getSurfaceIds(): string[] {\n return Array.from(this.stores.keys())\n }\n\n /**\n * Get or create a store for a surface\n * Creates a new store with empty initial state if it doesn't exist\n */\n getOrCreateStore<T>(surfaceId: string, initialState?: T): StateStore<T> {\n const existing = this.getStore<T>(surfaceId)\n if (existing) {\n return existing\n }\n\n return this.createStore<T>(surfaceId, initialState ?? ({} as T))\n }\n\n private normalizeInitialState<T>(initialState: T): Record<string, unknown> {\n // If already an object (but not null/array), use it directly\n if (initialState !== null && typeof initialState === 'object' && !Array.isArray(initialState)) {\n return initialState as Record<string, unknown>\n }\n\n // Otherwise, wrap in a 'value' key\n return { value: initialState }\n }\n}\n\n/**\n * Create a surface state manager\n */\nexport function createSurfaceStateManager(config?: StateStoreConfig): SurfaceStateManager {\n return new DefaultSurfaceStateManager(config)\n}\n"]}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * In-Memory State Store
3
+ *
4
+ * In-memory state store implementation with reactive subscriptions
5
+ *
6
+ * @module @pwfabric/runtime/state/store
7
+ */
8
+ import type { StateStore, StateChangeListener, StateStoreConfig, StateHistoryEntry } from './types.js';
9
+ /**
10
+ * In-memory implementation of StateStore with reactive subscriptions
11
+ */
12
+ export declare class InMemoryStateStore<T = unknown> implements StateStore<T> {
13
+ private readonly state;
14
+ private readonly listeners;
15
+ private readonly history;
16
+ private readonly config;
17
+ constructor(initialState?: Record<string, T>, config?: StateStoreConfig);
18
+ get(key: string): T | undefined;
19
+ set(key: string, value: T): void;
20
+ subscribe(key: string, listener: StateChangeListener<T>): () => void;
21
+ clear(): void;
22
+ keys(): string[];
23
+ has(key: string): boolean;
24
+ size(): number;
25
+ /**
26
+ * Get state change history for a key (if history is enabled)
27
+ */
28
+ getHistory(key: string): readonly StateHistoryEntry<T>[];
29
+ /**
30
+ * Get all current state as an object
31
+ */
32
+ getSnapshot(): Record<string, T>;
33
+ private notifyListeners;
34
+ private recordHistory;
35
+ private maybeClone;
36
+ }
37
+ /**
38
+ * Create an in-memory state store
39
+ */
40
+ export declare function createStateStore<T = unknown>(initialState?: Record<string, T>, config?: StateStoreConfig): StateStore<T>;
@@ -0,0 +1,145 @@
1
+ /**
2
+ * In-Memory State Store
3
+ *
4
+ * In-memory state store implementation with reactive subscriptions
5
+ *
6
+ * @module @pwfabric/runtime/state/store
7
+ */
8
+ // ============================================================
9
+ // IN-MEMORY STATE STORE
10
+ // ============================================================
11
+ /**
12
+ * In-memory implementation of StateStore with reactive subscriptions
13
+ */
14
+ export class InMemoryStateStore {
15
+ state = new Map();
16
+ listeners = new Map();
17
+ history = new Map();
18
+ config;
19
+ constructor(initialState = {}, config = {}) {
20
+ this.config = {
21
+ enableHistory: config.enableHistory ?? false,
22
+ maxHistorySize: config.maxHistorySize ?? 100,
23
+ deepClone: config.deepClone ?? false,
24
+ };
25
+ // Initialize with initial state
26
+ for (const [key, value] of Object.entries(initialState)) {
27
+ this.state.set(key, this.maybeClone(value));
28
+ }
29
+ }
30
+ get(key) {
31
+ const value = this.state.get(key);
32
+ return value !== undefined ? this.maybeClone(value) : undefined;
33
+ }
34
+ set(key, value) {
35
+ const previousValue = this.state.get(key);
36
+ const newValue = this.maybeClone(value);
37
+ this.state.set(key, newValue);
38
+ // Record history if enabled
39
+ if (this.config.enableHistory) {
40
+ this.recordHistory(key, newValue);
41
+ }
42
+ // Notify listeners
43
+ const event = {
44
+ key,
45
+ previousValue,
46
+ newValue,
47
+ timestamp: Date.now(),
48
+ };
49
+ this.notifyListeners(key, newValue, event);
50
+ }
51
+ subscribe(key, listener) {
52
+ let keyListeners = this.listeners.get(key);
53
+ if (!keyListeners) {
54
+ keyListeners = new Set();
55
+ this.listeners.set(key, keyListeners);
56
+ }
57
+ keyListeners.add(listener);
58
+ // Return unsubscribe function
59
+ return () => {
60
+ keyListeners.delete(listener);
61
+ if (keyListeners.size === 0) {
62
+ this.listeners.delete(key);
63
+ }
64
+ };
65
+ }
66
+ clear() {
67
+ this.state.clear();
68
+ this.listeners.clear();
69
+ this.history.clear();
70
+ }
71
+ keys() {
72
+ return Array.from(this.state.keys());
73
+ }
74
+ has(key) {
75
+ return this.state.has(key);
76
+ }
77
+ size() {
78
+ return this.state.size;
79
+ }
80
+ /**
81
+ * Get state change history for a key (if history is enabled)
82
+ */
83
+ getHistory(key) {
84
+ return this.history.get(key) ?? [];
85
+ }
86
+ /**
87
+ * Get all current state as an object
88
+ */
89
+ getSnapshot() {
90
+ const snapshot = {};
91
+ for (const [key, value] of this.state) {
92
+ snapshot[key] = this.maybeClone(value);
93
+ }
94
+ return snapshot;
95
+ }
96
+ notifyListeners(key, value, event) {
97
+ const keyListeners = this.listeners.get(key);
98
+ if (keyListeners) {
99
+ for (const listener of keyListeners) {
100
+ try {
101
+ listener(value, event);
102
+ }
103
+ catch {
104
+ // Swallow errors from listeners to prevent one bad listener from breaking others
105
+ }
106
+ }
107
+ }
108
+ }
109
+ recordHistory(key, value) {
110
+ let keyHistory = this.history.get(key);
111
+ if (!keyHistory) {
112
+ keyHistory = [];
113
+ this.history.set(key, keyHistory);
114
+ }
115
+ keyHistory.push({
116
+ value: this.maybeClone(value),
117
+ timestamp: Date.now(),
118
+ });
119
+ // Trim history if exceeds max size
120
+ while (keyHistory.length > this.config.maxHistorySize) {
121
+ keyHistory.shift();
122
+ }
123
+ }
124
+ maybeClone(value) {
125
+ if (!this.config.deepClone) {
126
+ return value;
127
+ }
128
+ // Simple deep clone using JSON (works for most cases)
129
+ // For more complex cases, a proper deep clone library would be needed
130
+ try {
131
+ return JSON.parse(JSON.stringify(value));
132
+ }
133
+ catch {
134
+ // If cloning fails, return original value
135
+ return value;
136
+ }
137
+ }
138
+ }
139
+ /**
140
+ * Create an in-memory state store
141
+ */
142
+ export function createStateStore(initialState, config) {
143
+ return new InMemoryStateStore(initialState, config);
144
+ }
145
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/state/store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * In-Memory State Store\n *\n * In-memory state store implementation with reactive subscriptions\n *\n * @module @pwfabric/runtime/state/store\n */\n\nimport type {\n StateStore,\n StateChangeEvent,\n StateChangeListener,\n StateStoreConfig,\n StateHistoryEntry,\n} from './types.js'\n\n// ============================================================\n// IN-MEMORY STATE STORE\n// ============================================================\n\n/**\n * In-memory implementation of StateStore with reactive subscriptions\n */\nexport class InMemoryStateStore<T = unknown> implements StateStore<T> {\n private readonly state = new Map<string, T>()\n private readonly listeners = new Map<string, Set<StateChangeListener<T>>>()\n private readonly history = new Map<string, StateHistoryEntry<T>[]>()\n private readonly config: Required<StateStoreConfig>\n\n constructor(initialState: Record<string, T> = {}, config: StateStoreConfig = {}) {\n this.config = {\n enableHistory: config.enableHistory ?? false,\n maxHistorySize: config.maxHistorySize ?? 100,\n deepClone: config.deepClone ?? false,\n }\n\n // Initialize with initial state\n for (const [key, value] of Object.entries(initialState)) {\n this.state.set(key, this.maybeClone(value))\n }\n }\n\n get(key: string): T | undefined {\n const value = this.state.get(key)\n return value !== undefined ? this.maybeClone(value) : undefined\n }\n\n set(key: string, value: T): void {\n const previousValue = this.state.get(key)\n const newValue = this.maybeClone(value)\n\n this.state.set(key, newValue)\n\n // Record history if enabled\n if (this.config.enableHistory) {\n this.recordHistory(key, newValue)\n }\n\n // Notify listeners\n const event: StateChangeEvent<T> = {\n key,\n previousValue,\n newValue,\n timestamp: Date.now(),\n }\n\n this.notifyListeners(key, newValue, event)\n }\n\n subscribe(key: string, listener: StateChangeListener<T>): () => void {\n let keyListeners = this.listeners.get(key)\n if (!keyListeners) {\n keyListeners = new Set()\n this.listeners.set(key, keyListeners)\n }\n\n keyListeners.add(listener)\n\n // Return unsubscribe function\n return () => {\n keyListeners.delete(listener)\n if (keyListeners.size === 0) {\n this.listeners.delete(key)\n }\n }\n }\n\n clear(): void {\n this.state.clear()\n this.listeners.clear()\n this.history.clear()\n }\n\n keys(): string[] {\n return Array.from(this.state.keys())\n }\n\n has(key: string): boolean {\n return this.state.has(key)\n }\n\n size(): number {\n return this.state.size\n }\n\n /**\n * Get state change history for a key (if history is enabled)\n */\n getHistory(key: string): readonly StateHistoryEntry<T>[] {\n return this.history.get(key) ?? []\n }\n\n /**\n * Get all current state as an object\n */\n getSnapshot(): Record<string, T> {\n const snapshot: Record<string, T> = {}\n for (const [key, value] of this.state) {\n snapshot[key] = this.maybeClone(value)\n }\n return snapshot\n }\n\n private notifyListeners(key: string, value: T, event: StateChangeEvent<T>): void {\n const keyListeners = this.listeners.get(key)\n if (keyListeners) {\n for (const listener of keyListeners) {\n try {\n listener(value, event)\n } catch {\n // Swallow errors from listeners to prevent one bad listener from breaking others\n }\n }\n }\n }\n\n private recordHistory(key: string, value: T): void {\n let keyHistory = this.history.get(key)\n if (!keyHistory) {\n keyHistory = []\n this.history.set(key, keyHistory)\n }\n\n keyHistory.push({\n value: this.maybeClone(value),\n timestamp: Date.now(),\n })\n\n // Trim history if exceeds max size\n while (keyHistory.length > this.config.maxHistorySize) {\n keyHistory.shift()\n }\n }\n\n private maybeClone(value: T): T {\n if (!this.config.deepClone) {\n return value\n }\n\n // Simple deep clone using JSON (works for most cases)\n // For more complex cases, a proper deep clone library would be needed\n try {\n return JSON.parse(JSON.stringify(value)) as T\n } catch {\n // If cloning fails, return original value\n return value\n }\n }\n}\n\n/**\n * Create an in-memory state store\n */\nexport function createStateStore<T = unknown>(\n initialState?: Record<string, T>,\n config?: StateStoreConfig\n): StateStore<T> {\n return new InMemoryStateStore<T>(initialState, config)\n}\n"]}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * State Management Types
3
+ *
4
+ * State management capability for surfaces
5
+ *
6
+ * @module @pwfabric/runtime/state/types
7
+ */
8
+ /**
9
+ * Event emitted when state changes
10
+ */
11
+ export interface StateChangeEvent<T = unknown> {
12
+ readonly key: string;
13
+ readonly previousValue: T | undefined;
14
+ readonly newValue: T;
15
+ readonly timestamp: number;
16
+ }
17
+ /**
18
+ * State change listener callback
19
+ */
20
+ export type StateChangeListener<T = unknown> = (value: T, event: StateChangeEvent<T>) => void;
21
+ /**
22
+ * State store interface for managing reactive state
23
+ */
24
+ export interface StateStore<T = unknown> {
25
+ /**
26
+ * Get a value from the store
27
+ */
28
+ get(key: string): T | undefined;
29
+ /**
30
+ * Set a value in the store
31
+ */
32
+ set(key: string, value: T): void;
33
+ /**
34
+ * Subscribe to changes for a specific key
35
+ * Returns an unsubscribe function
36
+ */
37
+ subscribe(key: string, listener: StateChangeListener<T>): () => void;
38
+ /**
39
+ * Clear all state from the store
40
+ */
41
+ clear(): void;
42
+ /**
43
+ * Get all keys in the store
44
+ */
45
+ keys(): string[];
46
+ /**
47
+ * Check if a key exists in the store
48
+ */
49
+ has(key: string): boolean;
50
+ /**
51
+ * Get the number of entries in the store
52
+ */
53
+ size(): number;
54
+ }
55
+ /**
56
+ * Manager for surface-scoped state stores
57
+ */
58
+ export interface SurfaceStateManager {
59
+ /**
60
+ * Create a new store for a surface with initial state
61
+ */
62
+ createStore<T>(surfaceId: string, initialState: T): StateStore<T>;
63
+ /**
64
+ * Get an existing store for a surface
65
+ */
66
+ getStore<T>(surfaceId: string): StateStore<T> | undefined;
67
+ /**
68
+ * Check if a store exists for a surface
69
+ */
70
+ hasStore(surfaceId: string): boolean;
71
+ /**
72
+ * Destroy a store for a surface
73
+ */
74
+ destroyStore(surfaceId: string): void;
75
+ /**
76
+ * Destroy all stores
77
+ */
78
+ destroyAll(): void;
79
+ /**
80
+ * Get all surface IDs with active stores
81
+ */
82
+ getSurfaceIds(): string[];
83
+ }
84
+ /**
85
+ * Configuration for state store
86
+ */
87
+ export interface StateStoreConfig {
88
+ /**
89
+ * Whether to enable state change history
90
+ */
91
+ readonly enableHistory?: boolean;
92
+ /**
93
+ * Maximum history entries to keep per key
94
+ */
95
+ readonly maxHistorySize?: number;
96
+ /**
97
+ * Whether to deep clone values on get/set
98
+ */
99
+ readonly deepClone?: boolean;
100
+ }
101
+ /**
102
+ * State history entry
103
+ */
104
+ export interface StateHistoryEntry<T = unknown> {
105
+ readonly value: T;
106
+ readonly timestamp: number;
107
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * State Management Types
3
+ *
4
+ * State management capability for surfaces
5
+ *
6
+ * @module @pwfabric/runtime/state/types
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/state/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG","sourcesContent":["/**\n * State Management Types\n *\n * State management capability for surfaces\n *\n * @module @pwfabric/runtime/state/types\n */\n\n// ============================================================\n// STATE CHANGE EVENT\n// ============================================================\n\n/**\n * Event emitted when state changes\n */\nexport interface StateChangeEvent<T = unknown> {\n readonly key: string\n readonly previousValue: T | undefined\n readonly newValue: T\n readonly timestamp: number\n}\n\n/**\n * State change listener callback\n */\nexport type StateChangeListener<T = unknown> = (value: T, event: StateChangeEvent<T>) => void\n\n// ============================================================\n// STATE STORE\n// ============================================================\n\n/**\n * State store interface for managing reactive state\n */\nexport interface StateStore<T = unknown> {\n /**\n * Get a value from the store\n */\n get(key: string): T | undefined\n\n /**\n * Set a value in the store\n */\n set(key: string, value: T): void\n\n /**\n * Subscribe to changes for a specific key\n * Returns an unsubscribe function\n */\n subscribe(key: string, listener: StateChangeListener<T>): () => void\n\n /**\n * Clear all state from the store\n */\n clear(): void\n\n /**\n * Get all keys in the store\n */\n keys(): string[]\n\n /**\n * Check if a key exists in the store\n */\n has(key: string): boolean\n\n /**\n * Get the number of entries in the store\n */\n size(): number\n}\n\n// ============================================================\n// SURFACE STATE MANAGER\n// ============================================================\n\n/**\n * Manager for surface-scoped state stores\n */\nexport interface SurfaceStateManager {\n /**\n * Create a new store for a surface with initial state\n */\n createStore<T>(surfaceId: string, initialState: T): StateStore<T>\n\n /**\n * Get an existing store for a surface\n */\n getStore<T>(surfaceId: string): StateStore<T> | undefined\n\n /**\n * Check if a store exists for a surface\n */\n hasStore(surfaceId: string): boolean\n\n /**\n * Destroy a store for a surface\n */\n destroyStore(surfaceId: string): void\n\n /**\n * Destroy all stores\n */\n destroyAll(): void\n\n /**\n * Get all surface IDs with active stores\n */\n getSurfaceIds(): string[]\n}\n\n// ============================================================\n// STATE CONFIGURATION\n// ============================================================\n\n/**\n * Configuration for state store\n */\nexport interface StateStoreConfig {\n /**\n * Whether to enable state change history\n */\n readonly enableHistory?: boolean\n\n /**\n * Maximum history entries to keep per key\n */\n readonly maxHistorySize?: number\n\n /**\n * Whether to deep clone values on get/set\n */\n readonly deepClone?: boolean\n}\n\n/**\n * State history entry\n */\nexport interface StateHistoryEntry<T = unknown> {\n readonly value: T\n readonly timestamp: number\n}\n"]}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Expression Evaluator
3
+ *
4
+ * Safe expression evaluation for surface rendering
5
+ *
6
+ * Expressions are used in conditionals, loops, and data bindings.
7
+ * This evaluator provides a safe, sandboxed way to evaluate expressions.
8
+ *
9
+ * @module @pwfabric/runtime/surface/expression
10
+ */
11
+ export type ExpressionResult<T = unknown> = {
12
+ readonly success: true;
13
+ readonly value: T;
14
+ } | {
15
+ readonly success: false;
16
+ readonly error: string;
17
+ };
18
+ /**
19
+ * Expression context - the scope for evaluation
20
+ */
21
+ export interface ExpressionContext {
22
+ readonly data: Record<string, unknown>;
23
+ readonly helpers?: Record<string, (...args: unknown[]) => unknown>;
24
+ }
25
+ /**
26
+ * Resolve a dotted path in an object
27
+ * e.g., "user.profile.name" -> obj.user.profile.name
28
+ */
29
+ export declare function resolvePath(obj: unknown, path: string): unknown;
30
+ /**
31
+ * Evaluate an expression (the text between `{{` and `}}`).
32
+ *
33
+ * THE SAME PARSER AS THE BINDING EVALUATOR (binding/expression.ts). This used
34
+ * to be a regex/`split` evaluator of its own, and the two drifted: no
35
+ * parentheses, no arithmetic, helper arguments split on every comma — so
36
+ * `{{a == 'x' && (b || c)}}` failed, and a failed `visibleWhen` rendered its
37
+ * raw template, which counts as visible.
38
+ *
39
+ * Supported: paths (`user.name`, `items[0]`, `items.0`, hyphenated source ids
40
+ * `hero-stats.0.text`), literals, `! - +`, `* / %`, `+ -`, comparisons,
41
+ * `&& || ??` (short-circuit), `?:`, parentheses, array literals, helper calls
42
+ * (`join(xs, ', ')`) and a safe list of string / array / number methods
43
+ * (`name.toLowerCase().includes(q)`).
44
+ *
45
+ * Names resolve against `context.data`; a call resolves against
46
+ * `context.helpers`. In this mode a `-` between two name characters is part of
47
+ * the name (source ids are hyphenated) — write subtraction as `a - b`.
48
+ *
49
+ * A syntax error, an unknown helper or an unsupported method is a FAILURE
50
+ * (`success: false`), never a partial value.
51
+ */
52
+ export declare function evaluate(expression: string, context: ExpressionContext): ExpressionResult;
53
+ /**
54
+ * Interpolate expressions within a template string
55
+ * e.g., "Hello, {{user.name}}!" -> "Hello, John!"
56
+ */
57
+ export declare function interpolate(template: string, context: ExpressionContext): ExpressionResult<string>;
58
+ /**
59
+ * Default helper functions available in expressions
60
+ */
61
+ export declare const DEFAULT_HELPERS: Record<string, (...args: unknown[]) => unknown>;
62
+ /**
63
+ * Create an expression context with default helpers
64
+ */
65
+ export declare function createExpressionContext(data: Record<string, unknown>, additionalHelpers?: Record<string, (...args: unknown[]) => unknown>): ExpressionContext;
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Expression Evaluator
3
+ *
4
+ * Safe expression evaluation for surface rendering
5
+ *
6
+ * Expressions are used in conditionals, loops, and data bindings.
7
+ * This evaluator provides a safe, sandboxed way to evaluate expressions.
8
+ *
9
+ * @module @pwfabric/runtime/surface/expression
10
+ */
11
+ // ============================================================
12
+ // EXPRESSION TYPES
13
+ // ============================================================
14
+ /**
15
+ * Expression result
16
+ */
17
+ import { DEFAULT_BINDING_HELPERS, evaluateWithScope, readProperty } from '../binding/expression.js';
18
+ // ============================================================
19
+ // PATH RESOLUTION
20
+ // ============================================================
21
+ /**
22
+ * Resolve a dotted path in an object
23
+ * e.g., "user.profile.name" -> obj.user.profile.name
24
+ */
25
+ export function resolvePath(obj, path) {
26
+ if (!path || typeof obj !== 'object' || obj === null) {
27
+ return undefined;
28
+ }
29
+ const parts = path.split('.');
30
+ let current = obj;
31
+ for (const part of parts) {
32
+ if (current === null || current === undefined) {
33
+ return undefined;
34
+ }
35
+ // Handle array indexing: items[0]
36
+ const arrayMatch = part.match(/^(\w+)\[(\d+)\]$/);
37
+ if (arrayMatch) {
38
+ const prop = arrayMatch[1];
39
+ const index = arrayMatch[2];
40
+ if (prop && index) {
41
+ current = readProperty(current, prop);
42
+ if (Array.isArray(current)) {
43
+ current = current[parseInt(index, 10)];
44
+ }
45
+ else {
46
+ return undefined;
47
+ }
48
+ }
49
+ }
50
+ else if (typeof current === 'object') {
51
+ // A list of ONE record is read through — see readProperty.
52
+ current = readProperty(current, part);
53
+ }
54
+ else {
55
+ return undefined;
56
+ }
57
+ }
58
+ return current;
59
+ }
60
+ // ============================================================
61
+ // EXPRESSION EVALUATOR
62
+ // ============================================================
63
+ /**
64
+ * Evaluate an expression (the text between `{{` and `}}`).
65
+ *
66
+ * THE SAME PARSER AS THE BINDING EVALUATOR (binding/expression.ts). This used
67
+ * to be a regex/`split` evaluator of its own, and the two drifted: no
68
+ * parentheses, no arithmetic, helper arguments split on every comma — so
69
+ * `{{a == 'x' && (b || c)}}` failed, and a failed `visibleWhen` rendered its
70
+ * raw template, which counts as visible.
71
+ *
72
+ * Supported: paths (`user.name`, `items[0]`, `items.0`, hyphenated source ids
73
+ * `hero-stats.0.text`), literals, `! - +`, `* / %`, `+ -`, comparisons,
74
+ * `&& || ??` (short-circuit), `?:`, parentheses, array literals, helper calls
75
+ * (`join(xs, ', ')`) and a safe list of string / array / number methods
76
+ * (`name.toLowerCase().includes(q)`).
77
+ *
78
+ * Names resolve against `context.data`; a call resolves against
79
+ * `context.helpers`. In this mode a `-` between two name characters is part of
80
+ * the name (source ids are hyphenated) — write subtraction as `a - b`.
81
+ *
82
+ * A syntax error, an unknown helper or an unsupported method is a FAILURE
83
+ * (`success: false`), never a partial value.
84
+ */
85
+ export function evaluate(expression, context) {
86
+ try {
87
+ const data = context.data;
88
+ const helpers = context.helpers;
89
+ const value = evaluateWithScope(expression, {
90
+ lookup: (name) => data[name],
91
+ helper: (name) => helpers && Object.prototype.hasOwnProperty.call(helpers, name) ? helpers[name] : undefined,
92
+ }, { hyphenNames: true });
93
+ return { success: true, value };
94
+ }
95
+ catch (e) {
96
+ return { success: false, error: `Unable to evaluate expression: ${expression.trim()} — ${e instanceof Error ? e.message : String(e)}` };
97
+ }
98
+ }
99
+ // ============================================================
100
+ // INTERPOLATION
101
+ // ============================================================
102
+ /**
103
+ * Interpolate expressions within a template string
104
+ * e.g., "Hello, {{user.name}}!" -> "Hello, John!"
105
+ */
106
+ export function interpolate(template, context) {
107
+ const pattern = /\{\{(.+?)\}\}/g;
108
+ let result = template;
109
+ let match;
110
+ while ((match = pattern.exec(template)) !== null) {
111
+ const placeholder = match[0];
112
+ const expression = match[1];
113
+ if (!expression)
114
+ continue;
115
+ const evalResult = evaluate(expression.trim(), context);
116
+ if (!evalResult.success) {
117
+ return evalResult;
118
+ }
119
+ // CALLBACK replacer, NOT a string replacement. When its second argument is
120
+ // a string, `String.replace` treats `$&`, `$\``, `$'`, `$$` as REPLACEMENT
121
+ // PATTERNS: `"$$5"` in the data would print as `"$5"`, and `"a$&b"` would
122
+ // bring back the placeholder itself. The sibling evaluator
123
+ // (binding/expression.ts) uses a callback too.
124
+ const replacement = String(evalResult.value ?? '');
125
+ result = result.replace(placeholder, () => replacement);
126
+ }
127
+ return { success: true, value: result };
128
+ }
129
+ // ============================================================
130
+ // BUILT-IN HELPERS
131
+ // ============================================================
132
+ /**
133
+ * Default helper functions available in expressions
134
+ */
135
+ export const DEFAULT_HELPERS = {
136
+ // The binding evaluator's helper set comes first. Two evaluators exist —
137
+ // binding/expression (bindings, computed values) and this one (block props
138
+ // through resolveBlockExpressions) — and their helper lists drifted:
139
+ // `sumBy`, `groupCount`, `min`, `max`, `currency`, `date`… live in the
140
+ // binding set, and without it a KPI tile authored as
141
+ // `{{sumBy(customers,'mrr')}}` would render the raw template. One name, one meaning: the surface-specific entries below
142
+ // override where both define the same name.
143
+ ...DEFAULT_BINDING_HELPERS,
144
+ // String helpers
145
+ upper: (s) => String(s).toUpperCase(),
146
+ lower: (s) => String(s).toLowerCase(),
147
+ trim: (s) => String(s).trim(),
148
+ length: (s) => (Array.isArray(s) ? s.length : String(s).length),
149
+ concat: (...args) => args.map(String).join(''),
150
+ // Number helpers
151
+ // `round` comes from the binding set: `round(n)` as before, `round(n, 2)`
152
+ // to two decimals (this override used to drop the second argument).
153
+ floor: (n) => Math.floor(Number(n)),
154
+ ceil: (n) => Math.ceil(Number(n)),
155
+ abs: (n) => Math.abs(Number(n)),
156
+ // Array helpers
157
+ first: (arr) => (Array.isArray(arr) ? arr[0] : undefined),
158
+ last: (arr) => (Array.isArray(arr) ? arr[arr.length - 1] : undefined),
159
+ isEmpty: (v) => v === null || v === undefined || v === '' || (Array.isArray(v) && v.length === 0),
160
+ isNotEmpty: (v) => v !== null && v !== undefined && v !== '' && !(Array.isArray(v) && v.length === 0),
161
+ // Type helpers
162
+ typeof: (v) => typeof v,
163
+ isArray: (v) => Array.isArray(v),
164
+ isString: (v) => typeof v === 'string',
165
+ isNumber: (v) => typeof v === 'number',
166
+ isBool: (v) => typeof v === 'boolean',
167
+ // Formatting helpers
168
+ json: (v) => JSON.stringify(v),
169
+ };
170
+ /**
171
+ * Create an expression context with default helpers
172
+ */
173
+ export function createExpressionContext(data, additionalHelpers) {
174
+ return {
175
+ data,
176
+ helpers: { ...DEFAULT_HELPERS, ...additionalHelpers },
177
+ };
178
+ }
179
+ //# sourceMappingURL=expression.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expression.js","sourceRoot":"","sources":["../../src/surface/expression.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Expression Evaluator\n *\n * Safe expression evaluation for surface rendering\n *\n * Expressions are used in conditionals, loops, and data bindings.\n * This evaluator provides a safe, sandboxed way to evaluate expressions.\n *\n * @module @pwfabric/runtime/surface/expression\n */\n\n// ============================================================\n// EXPRESSION TYPES\n// ============================================================\n\n/**\n * Expression result\n */\nimport { DEFAULT_BINDING_HELPERS, evaluateWithScope, readProperty } from '../binding/expression.js'\n\nexport type ExpressionResult<T = unknown> =\n | { readonly success: true; readonly value: T }\n | { readonly success: false; readonly error: string }\n\n/**\n * Expression context - the scope for evaluation\n */\nexport interface ExpressionContext {\n readonly data: Record<string, unknown>\n readonly helpers?: Record<string, (...args: unknown[]) => unknown>\n}\n\n// ============================================================\n// PATH RESOLUTION\n// ============================================================\n\n/**\n * Resolve a dotted path in an object\n * e.g., \"user.profile.name\" -> obj.user.profile.name\n */\nexport function resolvePath(obj: unknown, path: string): unknown {\n if (!path || typeof obj !== 'object' || obj === null) {\n return undefined\n }\n\n const parts = path.split('.')\n let current: unknown = obj\n\n for (const part of parts) {\n if (current === null || current === undefined) {\n return undefined\n }\n\n // Handle array indexing: items[0]\n const arrayMatch = part.match(/^(\\w+)\\[(\\d+)\\]$/)\n if (arrayMatch) {\n const prop = arrayMatch[1]\n const index = arrayMatch[2]\n if (prop && index) {\n current = readProperty(current, prop)\n if (Array.isArray(current)) {\n current = current[parseInt(index, 10)]\n } else {\n return undefined\n }\n }\n } else if (typeof current === 'object') {\n // A list of ONE record is read through — see readProperty.\n current = readProperty(current, part)\n } else {\n return undefined\n }\n }\n\n return current\n}\n\n// ============================================================\n// EXPRESSION EVALUATOR\n// ============================================================\n\n/**\n * Evaluate an expression (the text between `{{` and `}}`).\n *\n * THE SAME PARSER AS THE BINDING EVALUATOR (binding/expression.ts). This used\n * to be a regex/`split` evaluator of its own, and the two drifted: no\n * parentheses, no arithmetic, helper arguments split on every comma — so\n * `{{a == 'x' && (b || c)}}` failed, and a failed `visibleWhen` rendered its\n * raw template, which counts as visible.\n *\n * Supported: paths (`user.name`, `items[0]`, `items.0`, hyphenated source ids\n * `hero-stats.0.text`), literals, `! - +`, `* / %`, `+ -`, comparisons,\n * `&& || ??` (short-circuit), `?:`, parentheses, array literals, helper calls\n * (`join(xs, ', ')`) and a safe list of string / array / number methods\n * (`name.toLowerCase().includes(q)`).\n *\n * Names resolve against `context.data`; a call resolves against\n * `context.helpers`. In this mode a `-` between two name characters is part of\n * the name (source ids are hyphenated) — write subtraction as `a - b`.\n *\n * A syntax error, an unknown helper or an unsupported method is a FAILURE\n * (`success: false`), never a partial value.\n */\nexport function evaluate(expression: string, context: ExpressionContext): ExpressionResult {\n try {\n const data = context.data\n const helpers = context.helpers\n const value = evaluateWithScope(\n expression,\n {\n lookup: (name) => data[name],\n helper: (name) =>\n helpers && Object.prototype.hasOwnProperty.call(helpers, name) ? helpers[name] : undefined,\n },\n { hyphenNames: true }\n )\n return { success: true, value }\n } catch (e) {\n return { success: false, error: `Unable to evaluate expression: ${expression.trim()} — ${e instanceof Error ? e.message : String(e)}` }\n }\n}\n\n// ============================================================\n// INTERPOLATION\n// ============================================================\n\n/**\n * Interpolate expressions within a template string\n * e.g., \"Hello, {{user.name}}!\" -> \"Hello, John!\"\n */\nexport function interpolate(\n template: string,\n context: ExpressionContext\n): ExpressionResult<string> {\n const pattern = /\\{\\{(.+?)\\}\\}/g\n let result = template\n let match: RegExpExecArray | null\n\n while ((match = pattern.exec(template)) !== null) {\n const placeholder = match[0]\n const expression = match[1]\n if (!expression) continue\n const evalResult = evaluate(expression.trim(), context)\n if (!evalResult.success) {\n return evalResult as ExpressionResult<string>\n }\n // CALLBACK replacer, NOT a string replacement. When its second argument is\n // a string, `String.replace` treats `$&`, `$\\``, `$'`, `$$` as REPLACEMENT\n // PATTERNS: `\"$$5\"` in the data would print as `\"$5\"`, and `\"a$&b\"` would\n // bring back the placeholder itself. The sibling evaluator\n // (binding/expression.ts) uses a callback too.\n const replacement = String(evalResult.value ?? '')\n result = result.replace(placeholder, () => replacement)\n }\n\n return { success: true, value: result }\n}\n\n// ============================================================\n// BUILT-IN HELPERS\n// ============================================================\n\n/**\n * Default helper functions available in expressions\n */\nexport const DEFAULT_HELPERS: Record<string, (...args: unknown[]) => unknown> = {\n // The binding evaluator's helper set comes first. Two evaluators exist —\n // binding/expression (bindings, computed values) and this one (block props\n // through resolveBlockExpressions) — and their helper lists drifted:\n // `sumBy`, `groupCount`, `min`, `max`, `currency`, `date`… live in the\n // binding set, and without it a KPI tile authored as\n // `{{sumBy(customers,'mrr')}}` would render the raw template. One name, one meaning: the surface-specific entries below\n // override where both define the same name.\n ...DEFAULT_BINDING_HELPERS,\n // String helpers\n upper: (s: unknown) => String(s).toUpperCase(),\n lower: (s: unknown) => String(s).toLowerCase(),\n trim: (s: unknown) => String(s).trim(),\n length: (s: unknown) => (Array.isArray(s) ? s.length : String(s).length),\n concat: (...args: unknown[]) => args.map(String).join(''),\n\n // Number helpers\n // `round` comes from the binding set: `round(n)` as before, `round(n, 2)`\n // to two decimals (this override used to drop the second argument).\n floor: (n: unknown) => Math.floor(Number(n)),\n ceil: (n: unknown) => Math.ceil(Number(n)),\n abs: (n: unknown) => Math.abs(Number(n)),\n\n // Array helpers\n first: (arr: unknown) => (Array.isArray(arr) ? arr[0] : undefined),\n last: (arr: unknown) => (Array.isArray(arr) ? arr[arr.length - 1] : undefined),\n isEmpty: (v: unknown) =>\n v === null || v === undefined || v === '' || (Array.isArray(v) && v.length === 0),\n isNotEmpty: (v: unknown) =>\n v !== null && v !== undefined && v !== '' && !(Array.isArray(v) && v.length === 0),\n\n // Type helpers\n typeof: (v: unknown) => typeof v,\n isArray: (v: unknown) => Array.isArray(v),\n isString: (v: unknown) => typeof v === 'string',\n isNumber: (v: unknown) => typeof v === 'number',\n isBool: (v: unknown) => typeof v === 'boolean',\n\n // Formatting helpers\n json: (v: unknown) => JSON.stringify(v),\n}\n\n/**\n * Create an expression context with default helpers\n */\nexport function createExpressionContext(\n data: Record<string, unknown>,\n additionalHelpers?: Record<string, (...args: unknown[]) => unknown>\n): ExpressionContext {\n return {\n data,\n helpers: { ...DEFAULT_HELPERS, ...additionalHelpers },\n }\n}\n"]}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Surface Rendering Module
3
+ *
4
+ * Surface JSON interpreter, renderer, layout system, and primitives
5
+ *
6
+ * This module provides the complete surface rendering pipeline:
7
+ * - JSON interpretation and validation
8
+ * - Layout resolution (slots, conditionals, loops)
9
+ * - Deterministic rendering
10
+ * - Built-in primitives
11
+ *
12
+ * @module @pwfabric/runtime/surface
13
+ */
14
+ export type { PrimitiveType, BaseNodeProps, RenderNode, SurfaceJSON, BindingJSON, LayoutJSON, RenderContext, RenderResult, RenderOutput, RenderError, RenderErrorCode, } from './types.js';
15
+ export { createNode, createRenderContext, createChildContext, renderSuccess, renderError, } from './types.js';
16
+ export type { ExpressionResult, ExpressionContext } from './expression.js';
17
+ export { evaluate, interpolate, resolvePath, createExpressionContext, DEFAULT_HELPERS, } from './expression.js';
18
+ export type { LayoutResult } from './layout.js';
19
+ export { resolveLayout, createSlotMap, extractSlots, composeLayouts, wrapInContainer, validateLayout, } from './layout.js';
20
+ export type { TextProps, ContainerProps, ButtonProps, InputProps, ImageProps, LinkProps, ListProps, HeadingProps, SpacerProps, DividerProps, SlotProps, ConditionalProps, LoopProps, PrimitiveDefinition, PropDefinition, } from './primitives.js';
21
+ export { PRIMITIVE_DEFINITIONS, text, container, button, heading, spacer, divider, isPrimitive, getPrimitiveDefinition, } from './primitives.js';
22
+ export { surfaceJsonSchema, layoutJsonSchema, bindingJsonSchema, environmentSchema, isSurfaceJSON, isLayoutJSON, isBindingJSON, } from './schemas.js';
23
+ export type { InterpretedSurface, InterpretationResult, InterpretSurfaceOptions, } from './interpreter.js';
24
+ export { interpretSurface, parseSurfaceJSON, SurfaceBuilder, surface, createSurfaceContext, } from './interpreter.js';
25
+ export type { RenderOptions, SurfaceRenderer } from './renderer.js';
26
+ export { DeterministicRenderer, createRenderer, renderSurface, isRenderSuccess, isRenderError, serializeNode, serializeOutput, hashNode, verifyDeterminism, } from './renderer.js';
27
+ export type { BlockPropsValidationResult, BlockPropsValidationOptions, LayoutPropsIssue, ManifestPropSpec, BlockManifestPropsMap, ManifestPropFinding, ManifestPropFindingCode, } from './validation.js';
28
+ export { validateBlockProps, validateLayoutProps, blockManifestPropFindings, manifestPropFindings, } from './validation.js';
29
+ export type { MapTransformConfig, FilterTransformConfig, PickTransformConfig, OmitTransformConfig, CustomTransformConfig, TypedTransformConfig, TransformValidationResult, } from './transforms.js';
30
+ export { mapTransformConfigSchema, filterTransformConfigSchema, pickTransformConfigSchema, omitTransformConfigSchema, customTransformConfigSchema, validateTransformConfig, narrowTransformDescriptor, createMapTransform, createFilterTransform, createPickTransform, createOmitTransform, createCustomTransform, } from './transforms.js';
31
+ export type { TypedWebOutput, TypedApiOutput, TypedCliOutput, OutputFactoryResult, } from './output.js';
32
+ export { createWebOutput, createApiOutput, createCliOutput } from './output.js';