@pwfabric/runtime 0.0.0-stage → 1.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (603) hide show
  1. package/LICENSE +90 -0
  2. package/README.md +13 -2
  3. package/dist/__tests__/dom-test-setup.d.ts +21 -0
  4. package/dist/__tests__/dom-test-setup.d.ts.map +1 -0
  5. package/dist/__tests__/dom-test-setup.js +36 -0
  6. package/dist/__tests__/dom-test-setup.js.map +1 -0
  7. package/dist/a11y/announcer.d.ts +66 -0
  8. package/dist/a11y/announcer.d.ts.map +1 -0
  9. package/dist/a11y/announcer.js +140 -0
  10. package/dist/a11y/announcer.js.map +1 -0
  11. package/dist/a11y/contrast.d.ts +55 -0
  12. package/dist/a11y/contrast.d.ts.map +1 -0
  13. package/dist/a11y/contrast.js +93 -0
  14. package/dist/a11y/contrast.js.map +1 -0
  15. package/dist/a11y/focus.d.ts +124 -0
  16. package/dist/a11y/focus.d.ts.map +1 -0
  17. package/dist/a11y/focus.js +282 -0
  18. package/dist/a11y/focus.js.map +1 -0
  19. package/dist/a11y/index.d.ts +22 -0
  20. package/dist/a11y/index.d.ts.map +1 -0
  21. package/dist/a11y/index.js +18 -0
  22. package/dist/a11y/index.js.map +1 -0
  23. package/dist/a11y/keyboard.d.ts +145 -0
  24. package/dist/a11y/keyboard.d.ts.map +1 -0
  25. package/dist/a11y/keyboard.js +317 -0
  26. package/dist/a11y/keyboard.js.map +1 -0
  27. package/dist/adapters/default-image.d.ts +26 -0
  28. package/dist/adapters/default-image.d.ts.map +1 -0
  29. package/dist/adapters/default-image.js +37 -0
  30. package/dist/adapters/default-image.js.map +1 -0
  31. package/dist/adapters/index.d.ts +28 -0
  32. package/dist/adapters/index.d.ts.map +1 -0
  33. package/dist/adapters/index.js +28 -0
  34. package/dist/adapters/index.js.map +1 -0
  35. package/dist/adapters/next-image.d.ts +39 -0
  36. package/dist/adapters/next-image.d.ts.map +1 -0
  37. package/dist/adapters/next-image.js +124 -0
  38. package/dist/adapters/next-image.js.map +1 -0
  39. package/dist/adapters/types.d.ts +62 -0
  40. package/dist/adapters/types.d.ts.map +1 -0
  41. package/dist/adapters/types.js +11 -0
  42. package/dist/adapters/types.js.map +1 -0
  43. package/dist/analytics/index.d.ts +15 -0
  44. package/dist/analytics/index.d.ts.map +1 -0
  45. package/dist/analytics/index.js +15 -0
  46. package/dist/analytics/index.js.map +1 -0
  47. package/dist/analytics/tracker.d.ts +66 -0
  48. package/dist/analytics/tracker.d.ts.map +1 -0
  49. package/dist/analytics/tracker.js +251 -0
  50. package/dist/analytics/tracker.js.map +1 -0
  51. package/dist/analytics/types.d.ts +131 -0
  52. package/dist/analytics/types.d.ts.map +1 -0
  53. package/dist/analytics/types.js +11 -0
  54. package/dist/analytics/types.js.map +1 -0
  55. package/dist/auth/index.d.ts +16 -0
  56. package/dist/auth/index.d.ts.map +1 -0
  57. package/dist/auth/index.js +14 -0
  58. package/dist/auth/index.js.map +1 -0
  59. package/dist/auth/provider.d.ts +133 -0
  60. package/dist/auth/provider.d.ts.map +1 -0
  61. package/dist/auth/provider.js +473 -0
  62. package/dist/auth/provider.js.map +1 -0
  63. package/dist/auth/types.d.ts +118 -0
  64. package/dist/auth/types.d.ts.map +1 -0
  65. package/dist/auth/types.js +9 -0
  66. package/dist/auth/types.js.map +1 -0
  67. package/dist/binding/collection.d.ts +191 -0
  68. package/dist/binding/collection.d.ts.map +1 -0
  69. package/dist/binding/collection.js +358 -0
  70. package/dist/binding/collection.js.map +1 -0
  71. package/dist/binding/datasource.d.ts +320 -0
  72. package/dist/binding/datasource.d.ts.map +1 -0
  73. package/dist/binding/datasource.js +556 -0
  74. package/dist/binding/datasource.js.map +1 -0
  75. package/dist/binding/engine.d.ts +66 -0
  76. package/dist/binding/engine.d.ts.map +1 -0
  77. package/dist/binding/engine.js +268 -0
  78. package/dist/binding/engine.js.map +1 -0
  79. package/dist/binding/expression.d.ts +151 -0
  80. package/dist/binding/expression.d.ts.map +1 -0
  81. package/dist/binding/expression.js +787 -0
  82. package/dist/binding/expression.js.map +1 -0
  83. package/dist/binding/index.d.ts +20 -0
  84. package/dist/binding/index.d.ts.map +1 -0
  85. package/dist/binding/index.js +14 -0
  86. package/dist/binding/index.js.map +1 -0
  87. package/dist/binding/two-way.d.ts +150 -0
  88. package/dist/binding/two-way.d.ts.map +1 -0
  89. package/dist/binding/two-way.js +462 -0
  90. package/dist/binding/two-way.js.map +1 -0
  91. package/dist/binding/types.d.ts +120 -0
  92. package/dist/binding/types.d.ts.map +1 -0
  93. package/dist/binding/types.js +9 -0
  94. package/dist/binding/types.js.map +1 -0
  95. package/dist/blocks/__test-fixtures__/block-fixtures.d.ts +40 -0
  96. package/dist/blocks/__test-fixtures__/block-fixtures.d.ts.map +1 -0
  97. package/dist/blocks/__test-fixtures__/block-fixtures.js +506 -0
  98. package/dist/blocks/__test-fixtures__/block-fixtures.js.map +1 -0
  99. package/dist/blocks/component-types.d.ts +82 -0
  100. package/dist/blocks/component-types.d.ts.map +1 -0
  101. package/dist/blocks/component-types.js +11 -0
  102. package/dist/blocks/component-types.js.map +1 -0
  103. package/dist/blocks/composition-rules.d.ts +169 -0
  104. package/dist/blocks/composition-rules.d.ts.map +1 -0
  105. package/dist/blocks/composition-rules.js +391 -0
  106. package/dist/blocks/composition-rules.js.map +1 -0
  107. package/dist/blocks/hooks.d.ts +32 -0
  108. package/dist/blocks/hooks.d.ts.map +1 -0
  109. package/dist/blocks/hooks.js +42 -0
  110. package/dist/blocks/hooks.js.map +1 -0
  111. package/dist/blocks/index.d.ts +16 -0
  112. package/dist/blocks/index.d.ts.map +1 -0
  113. package/dist/blocks/index.js +24 -0
  114. package/dist/blocks/index.js.map +1 -0
  115. package/dist/blocks/registry.d.ts +85 -0
  116. package/dist/blocks/registry.d.ts.map +1 -0
  117. package/dist/blocks/registry.js +136 -0
  118. package/dist/blocks/registry.js.map +1 -0
  119. package/dist/blocks/rule-engine.d.ts +132 -0
  120. package/dist/blocks/rule-engine.d.ts.map +1 -0
  121. package/dist/blocks/rule-engine.js +321 -0
  122. package/dist/blocks/rule-engine.js.map +1 -0
  123. package/dist/blocks/surface-event-context.d.ts +14 -0
  124. package/dist/blocks/surface-event-context.d.ts.map +1 -0
  125. package/dist/blocks/surface-event-context.js +14 -0
  126. package/dist/blocks/surface-event-context.js.map +1 -0
  127. package/dist/blocks/surface-id-context.d.ts +14 -0
  128. package/dist/blocks/surface-id-context.d.ts.map +1 -0
  129. package/dist/blocks/surface-id-context.js +15 -0
  130. package/dist/blocks/surface-id-context.js.map +1 -0
  131. package/dist/bus.d.ts +42 -0
  132. package/dist/bus.d.ts.map +1 -0
  133. package/dist/bus.js +158 -0
  134. package/dist/bus.js.map +1 -0
  135. package/dist/cache/index.d.ts +10 -0
  136. package/dist/cache/index.d.ts.map +1 -0
  137. package/dist/cache/index.js +10 -0
  138. package/dist/cache/index.js.map +1 -0
  139. package/dist/cache/memory.d.ts +33 -0
  140. package/dist/cache/memory.d.ts.map +1 -0
  141. package/dist/cache/memory.js +138 -0
  142. package/dist/cache/memory.js.map +1 -0
  143. package/dist/cache/types.d.ts +63 -0
  144. package/dist/cache/types.d.ts.map +1 -0
  145. package/dist/cache/types.js +9 -0
  146. package/dist/cache/types.js.map +1 -0
  147. package/dist/capability/index.d.ts +73 -0
  148. package/dist/capability/index.d.ts.map +1 -0
  149. package/dist/capability/index.js +87 -0
  150. package/dist/capability/index.js.map +1 -0
  151. package/dist/capability/kernel-capabilities.d.ts +32 -0
  152. package/dist/capability/kernel-capabilities.d.ts.map +1 -0
  153. package/dist/capability/kernel-capabilities.js +36 -0
  154. package/dist/capability/kernel-capabilities.js.map +1 -0
  155. package/dist/capability/platform-capabilities.d.ts +72 -0
  156. package/dist/capability/platform-capabilities.d.ts.map +1 -0
  157. package/dist/capability/platform-capabilities.js +267 -0
  158. package/dist/capability/platform-capabilities.js.map +1 -0
  159. package/dist/capability/type-mapping.d.ts +71 -0
  160. package/dist/capability/type-mapping.d.ts.map +1 -0
  161. package/dist/capability/type-mapping.js +107 -0
  162. package/dist/capability/type-mapping.js.map +1 -0
  163. package/dist/capability/validation.d.ts +47 -0
  164. package/dist/capability/validation.d.ts.map +1 -0
  165. package/dist/capability/validation.js +54 -0
  166. package/dist/capability/validation.js.map +1 -0
  167. package/dist/connectors/declared-connector.d.ts +49 -0
  168. package/dist/connectors/declared-connector.d.ts.map +1 -0
  169. package/dist/connectors/declared-connector.js +333 -0
  170. package/dist/connectors/declared-connector.js.map +1 -0
  171. package/dist/connectors/engine-registry.d.ts +51 -0
  172. package/dist/connectors/engine-registry.d.ts.map +1 -0
  173. package/dist/connectors/engine-registry.js +135 -0
  174. package/dist/connectors/engine-registry.js.map +1 -0
  175. package/dist/connectors/index.d.ts +15 -0
  176. package/dist/connectors/index.d.ts.map +1 -0
  177. package/dist/connectors/index.js +14 -0
  178. package/dist/connectors/index.js.map +1 -0
  179. package/dist/connectors/module-loader.d.ts +71 -0
  180. package/dist/connectors/module-loader.d.ts.map +1 -0
  181. package/dist/connectors/module-loader.js +143 -0
  182. package/dist/connectors/module-loader.js.map +1 -0
  183. package/dist/connectors/types.d.ts +175 -0
  184. package/dist/connectors/types.d.ts.map +1 -0
  185. package/dist/connectors/types.js +23 -0
  186. package/dist/connectors/types.js.map +1 -0
  187. package/dist/context.d.ts +28 -0
  188. package/dist/context.d.ts.map +1 -0
  189. package/dist/context.js +38 -0
  190. package/dist/context.js.map +1 -0
  191. package/dist/data/DataCapabilityProvider.d.ts +40 -0
  192. package/dist/data/DataCapabilityProvider.d.ts.map +1 -0
  193. package/dist/data/DataCapabilityProvider.js +58 -0
  194. package/dist/data/DataCapabilityProvider.js.map +1 -0
  195. package/dist/data/index.d.ts +18 -0
  196. package/dist/data/index.d.ts.map +1 -0
  197. package/dist/data/index.js +18 -0
  198. package/dist/data/index.js.map +1 -0
  199. package/dist/data/manager.d.ts +41 -0
  200. package/dist/data/manager.d.ts.map +1 -0
  201. package/dist/data/manager.js +442 -0
  202. package/dist/data/manager.js.map +1 -0
  203. package/dist/data/types.d.ts +219 -0
  204. package/dist/data/types.d.ts.map +1 -0
  205. package/dist/data/types.js +2 -0
  206. package/dist/data/types.js.map +1 -0
  207. package/dist/entity/aggregate.d.ts +9 -0
  208. package/dist/entity/aggregate.d.ts.map +1 -0
  209. package/dist/entity/aggregate.js +24 -0
  210. package/dist/entity/aggregate.js.map +1 -0
  211. package/dist/entity/apply-query.d.ts +59 -0
  212. package/dist/entity/apply-query.d.ts.map +1 -0
  213. package/dist/entity/apply-query.js +264 -0
  214. package/dist/entity/apply-query.js.map +1 -0
  215. package/dist/entity/behavior.d.ts +95 -0
  216. package/dist/entity/behavior.d.ts.map +1 -0
  217. package/dist/entity/behavior.js +78 -0
  218. package/dist/entity/behavior.js.map +1 -0
  219. package/dist/entity/connector.d.ts +142 -0
  220. package/dist/entity/connector.d.ts.map +1 -0
  221. package/dist/entity/connector.js +89 -0
  222. package/dist/entity/connector.js.map +1 -0
  223. package/dist/entity/connectors/index.d.ts +13 -0
  224. package/dist/entity/connectors/index.d.ts.map +1 -0
  225. package/dist/entity/connectors/index.js +11 -0
  226. package/dist/entity/connectors/index.js.map +1 -0
  227. package/dist/entity/connectors/static.d.ts +52 -0
  228. package/dist/entity/connectors/static.d.ts.map +1 -0
  229. package/dist/entity/connectors/static.js +245 -0
  230. package/dist/entity/connectors/static.js.map +1 -0
  231. package/dist/entity/entity-datasource.d.ts +51 -0
  232. package/dist/entity/entity-datasource.d.ts.map +1 -0
  233. package/dist/entity/entity-datasource.js +33 -0
  234. package/dist/entity/entity-datasource.js.map +1 -0
  235. package/dist/entity/facade.d.ts +71 -0
  236. package/dist/entity/facade.d.ts.map +1 -0
  237. package/dist/entity/facade.js +70 -0
  238. package/dist/entity/facade.js.map +1 -0
  239. package/dist/entity/http-connector.d.ts +124 -0
  240. package/dist/entity/http-connector.d.ts.map +1 -0
  241. package/dist/entity/http-connector.js +295 -0
  242. package/dist/entity/http-connector.js.map +1 -0
  243. package/dist/entity/index.d.ts +39 -0
  244. package/dist/entity/index.d.ts.map +1 -0
  245. package/dist/entity/index.js +31 -0
  246. package/dist/entity/index.js.map +1 -0
  247. package/dist/entity/postgres-connector.d.ts +65 -0
  248. package/dist/entity/postgres-connector.d.ts.map +1 -0
  249. package/dist/entity/postgres-connector.js +239 -0
  250. package/dist/entity/postgres-connector.js.map +1 -0
  251. package/dist/entity/registry.d.ts +60 -0
  252. package/dist/entity/registry.d.ts.map +1 -0
  253. package/dist/entity/registry.js +90 -0
  254. package/dist/entity/registry.js.map +1 -0
  255. package/dist/entity/store.d.ts +67 -0
  256. package/dist/entity/store.d.ts.map +1 -0
  257. package/dist/entity/store.js +349 -0
  258. package/dist/entity/store.js.map +1 -0
  259. package/dist/entity/types.d.ts +181 -0
  260. package/dist/entity/types.d.ts.map +1 -0
  261. package/dist/entity/types.js +10 -0
  262. package/dist/entity/types.js.map +1 -0
  263. package/dist/execution-context.d.ts +89 -0
  264. package/dist/execution-context.d.ts.map +1 -0
  265. package/dist/execution-context.js +146 -0
  266. package/dist/execution-context.js.map +1 -0
  267. package/dist/executor.d.ts +28 -0
  268. package/dist/executor.d.ts.map +1 -0
  269. package/dist/executor.js +33 -0
  270. package/dist/executor.js.map +1 -0
  271. package/dist/forms/form-entity-bridge.d.ts +95 -0
  272. package/dist/forms/form-entity-bridge.d.ts.map +1 -0
  273. package/dist/forms/form-entity-bridge.js +96 -0
  274. package/dist/forms/form-entity-bridge.js.map +1 -0
  275. package/dist/forms/form-write-target.d.ts +35 -0
  276. package/dist/forms/form-write-target.d.ts.map +1 -0
  277. package/dist/forms/form-write-target.js +81 -0
  278. package/dist/forms/form-write-target.js.map +1 -0
  279. package/dist/forms/index.d.ts +23 -0
  280. package/dist/forms/index.d.ts.map +1 -0
  281. package/dist/forms/index.js +25 -0
  282. package/dist/forms/index.js.map +1 -0
  283. package/dist/forms/named-control-values.d.ts +28 -0
  284. package/dist/forms/named-control-values.d.ts.map +1 -0
  285. package/dist/forms/named-control-values.js +42 -0
  286. package/dist/forms/named-control-values.js.map +1 -0
  287. package/dist/forms/processor.d.ts +56 -0
  288. package/dist/forms/processor.d.ts.map +1 -0
  289. package/dist/forms/processor.js +154 -0
  290. package/dist/forms/processor.js.map +1 -0
  291. package/dist/forms/types.d.ts +175 -0
  292. package/dist/forms/types.d.ts.map +1 -0
  293. package/dist/forms/types.js +33 -0
  294. package/dist/forms/types.js.map +1 -0
  295. package/dist/forms/validator.d.ts +62 -0
  296. package/dist/forms/validator.d.ts.map +1 -0
  297. package/dist/forms/validator.js +218 -0
  298. package/dist/forms/validator.js.map +1 -0
  299. package/dist/graph/index.d.ts +11 -0
  300. package/dist/graph/index.d.ts.map +1 -0
  301. package/dist/graph/index.js +9 -0
  302. package/dist/graph/index.js.map +1 -0
  303. package/dist/graph/resolver.d.ts +67 -0
  304. package/dist/graph/resolver.d.ts.map +1 -0
  305. package/dist/graph/resolver.js +243 -0
  306. package/dist/graph/resolver.js.map +1 -0
  307. package/dist/graph/types.d.ts +126 -0
  308. package/dist/graph/types.d.ts.map +1 -0
  309. package/dist/graph/types.js +9 -0
  310. package/dist/graph/types.js.map +1 -0
  311. package/dist/hooks/useInstalledAtoms.d.ts +97 -0
  312. package/dist/hooks/useInstalledAtoms.d.ts.map +1 -0
  313. package/dist/hooks/useInstalledAtoms.js +92 -0
  314. package/dist/hooks/useInstalledAtoms.js.map +1 -0
  315. package/dist/i18n/index.d.ts +16 -0
  316. package/dist/i18n/index.d.ts.map +1 -0
  317. package/dist/i18n/index.js +14 -0
  318. package/dist/i18n/index.js.map +1 -0
  319. package/dist/i18n/translator.d.ts +77 -0
  320. package/dist/i18n/translator.d.ts.map +1 -0
  321. package/dist/i18n/translator.js +357 -0
  322. package/dist/i18n/translator.js.map +1 -0
  323. package/dist/i18n/types.d.ts +94 -0
  324. package/dist/i18n/types.d.ts.map +1 -0
  325. package/dist/i18n/types.js +9 -0
  326. package/dist/i18n/types.js.map +1 -0
  327. package/dist/index.d.ts +65 -0
  328. package/dist/index.d.ts.map +1 -0
  329. package/dist/index.js +95 -0
  330. package/dist/index.js.map +1 -0
  331. package/dist/kernel.d.ts +48 -0
  332. package/dist/kernel.d.ts.map +1 -0
  333. package/dist/kernel.js +258 -0
  334. package/dist/kernel.js.map +1 -0
  335. package/dist/perf/budget.d.ts +93 -0
  336. package/dist/perf/budget.d.ts.map +1 -0
  337. package/dist/perf/budget.js +122 -0
  338. package/dist/perf/budget.js.map +1 -0
  339. package/dist/perf/index.d.ts +17 -0
  340. package/dist/perf/index.d.ts.map +1 -0
  341. package/dist/perf/index.js +13 -0
  342. package/dist/perf/index.js.map +1 -0
  343. package/dist/perf/render-timer.d.ts +91 -0
  344. package/dist/perf/render-timer.d.ts.map +1 -0
  345. package/dist/perf/render-timer.js +136 -0
  346. package/dist/perf/render-timer.js.map +1 -0
  347. package/dist/perf/reporter.d.ts +127 -0
  348. package/dist/perf/reporter.d.ts.map +1 -0
  349. package/dist/perf/reporter.js +241 -0
  350. package/dist/perf/reporter.js.map +1 -0
  351. package/dist/perf/web-vitals.d.ts +112 -0
  352. package/dist/perf/web-vitals.d.ts.map +1 -0
  353. package/dist/perf/web-vitals.js +268 -0
  354. package/dist/perf/web-vitals.js.map +1 -0
  355. package/dist/registry.d.ts +64 -0
  356. package/dist/registry.d.ts.map +1 -0
  357. package/dist/registry.js +126 -0
  358. package/dist/registry.js.map +1 -0
  359. package/dist/render/BehaviorSurfaceProvider.d.ts +66 -0
  360. package/dist/render/BehaviorSurfaceProvider.d.ts.map +1 -0
  361. package/dist/render/BehaviorSurfaceProvider.js +185 -0
  362. package/dist/render/BehaviorSurfaceProvider.js.map +1 -0
  363. package/dist/render/BlockErrorBoundary.d.ts +27 -0
  364. package/dist/render/BlockErrorBoundary.d.ts.map +1 -0
  365. package/dist/render/BlockErrorBoundary.js +41 -0
  366. package/dist/render/BlockErrorBoundary.js.map +1 -0
  367. package/dist/render/DataBoundSurfaceRenderer.d.ts +79 -0
  368. package/dist/render/DataBoundSurfaceRenderer.d.ts.map +1 -0
  369. package/dist/render/DataBoundSurfaceRenderer.js +998 -0
  370. package/dist/render/DataBoundSurfaceRenderer.js.map +1 -0
  371. package/dist/render/DynamicBlockWrapper.d.ts +24 -0
  372. package/dist/render/DynamicBlockWrapper.d.ts.map +1 -0
  373. package/dist/render/DynamicBlockWrapper.js +117 -0
  374. package/dist/render/DynamicBlockWrapper.js.map +1 -0
  375. package/dist/render/appearance-resolver.d.ts +51 -0
  376. package/dist/render/appearance-resolver.d.ts.map +1 -0
  377. package/dist/render/appearance-resolver.js +78 -0
  378. package/dist/render/appearance-resolver.js.map +1 -0
  379. package/dist/render/capability-gate.d.ts +70 -0
  380. package/dist/render/capability-gate.d.ts.map +1 -0
  381. package/dist/render/capability-gate.js +94 -0
  382. package/dist/render/capability-gate.js.map +1 -0
  383. package/dist/render/conditional-states-css.d.ts +42 -0
  384. package/dist/render/conditional-states-css.d.ts.map +1 -0
  385. package/dist/render/conditional-states-css.js +82 -0
  386. package/dist/render/conditional-states-css.js.map +1 -0
  387. package/dist/render/connections-context.d.ts +32 -0
  388. package/dist/render/connections-context.d.ts.map +1 -0
  389. package/dist/render/connections-context.js +34 -0
  390. package/dist/render/connections-context.js.map +1 -0
  391. package/dist/render/dark-theme-css.d.ts +37 -0
  392. package/dist/render/dark-theme-css.d.ts.map +1 -0
  393. package/dist/render/dark-theme-css.js +67 -0
  394. package/dist/render/dark-theme-css.js.map +1 -0
  395. package/dist/render/data-binding-types.d.ts +192 -0
  396. package/dist/render/data-binding-types.d.ts.map +1 -0
  397. package/dist/render/data-binding-types.js +11 -0
  398. package/dist/render/data-binding-types.js.map +1 -0
  399. package/dist/render/data-cache.d.ts +31 -0
  400. package/dist/render/data-cache.d.ts.map +1 -0
  401. package/dist/render/data-cache.js +37 -0
  402. package/dist/render/data-cache.js.map +1 -0
  403. package/dist/render/derive-dark-theme.d.ts +18 -0
  404. package/dist/render/derive-dark-theme.d.ts.map +1 -0
  405. package/dist/render/derive-dark-theme.js +18 -0
  406. package/dist/render/derive-dark-theme.js.map +1 -0
  407. package/dist/render/dynamic-artifact-context.d.ts +78 -0
  408. package/dist/render/dynamic-artifact-context.d.ts.map +1 -0
  409. package/dist/render/dynamic-artifact-context.js +89 -0
  410. package/dist/render/dynamic-artifact-context.js.map +1 -0
  411. package/dist/render/dynamic-block-loader.d.ts +81 -0
  412. package/dist/render/dynamic-block-loader.d.ts.map +1 -0
  413. package/dist/render/dynamic-block-loader.js +197 -0
  414. package/dist/render/dynamic-block-loader.js.map +1 -0
  415. package/dist/render/endpoint.d.ts +19 -0
  416. package/dist/render/endpoint.d.ts.map +1 -0
  417. package/dist/render/endpoint.js +109 -0
  418. package/dist/render/endpoint.js.map +1 -0
  419. package/dist/render/entity-facade-context.d.ts +35 -0
  420. package/dist/render/entity-facade-context.d.ts.map +1 -0
  421. package/dist/render/entity-facade-context.js +37 -0
  422. package/dist/render/entity-facade-context.js.map +1 -0
  423. package/dist/render/group-states-css.d.ts +42 -0
  424. package/dist/render/group-states-css.d.ts.map +1 -0
  425. package/dist/render/group-states-css.js +73 -0
  426. package/dist/render/group-states-css.js.map +1 -0
  427. package/dist/render/hooks/useSurfaceEvents.d.ts +9 -0
  428. package/dist/render/hooks/useSurfaceEvents.d.ts.map +1 -0
  429. package/dist/render/hooks/useSurfaceEvents.js +9 -0
  430. package/dist/render/hooks/useSurfaceEvents.js.map +1 -0
  431. package/dist/render/hooks/useSurfaceId.d.ts +9 -0
  432. package/dist/render/hooks/useSurfaceId.d.ts.map +1 -0
  433. package/dist/render/hooks/useSurfaceId.js +9 -0
  434. package/dist/render/hooks/useSurfaceId.js.map +1 -0
  435. package/dist/render/index.d.ts +49 -0
  436. package/dist/render/index.d.ts.map +1 -0
  437. package/dist/render/index.js +61 -0
  438. package/dist/render/index.js.map +1 -0
  439. package/dist/render/interaction-rule-engine.d.ts +13 -0
  440. package/dist/render/interaction-rule-engine.d.ts.map +1 -0
  441. package/dist/render/interaction-rule-engine.js +47 -0
  442. package/dist/render/interaction-rule-engine.js.map +1 -0
  443. package/dist/render/keyframes-css.d.ts +32 -0
  444. package/dist/render/keyframes-css.d.ts.map +1 -0
  445. package/dist/render/keyframes-css.js +44 -0
  446. package/dist/render/keyframes-css.js.map +1 -0
  447. package/dist/render/query-state.d.ts +4 -0
  448. package/dist/render/query-state.d.ts.map +1 -0
  449. package/dist/render/query-state.js +70 -0
  450. package/dist/render/query-state.js.map +1 -0
  451. package/dist/render/renderer.d.ts +45 -0
  452. package/dist/render/renderer.d.ts.map +1 -0
  453. package/dist/render/renderer.js +937 -0
  454. package/dist/render/renderer.js.map +1 -0
  455. package/dist/render/resolve-expressions.d.ts +38 -0
  456. package/dist/render/resolve-expressions.d.ts.map +1 -0
  457. package/dist/render/resolve-expressions.js +309 -0
  458. package/dist/render/resolve-expressions.js.map +1 -0
  459. package/dist/render/responsive-style-css.d.ts +43 -0
  460. package/dist/render/responsive-style-css.d.ts.map +1 -0
  461. package/dist/render/responsive-style-css.js +123 -0
  462. package/dist/render/responsive-style-css.js.map +1 -0
  463. package/dist/render/responsive.d.ts +50 -0
  464. package/dist/render/responsive.d.ts.map +1 -0
  465. package/dist/render/responsive.js +99 -0
  466. package/dist/render/responsive.js.map +1 -0
  467. package/dist/render/scoped-css.d.ts +72 -0
  468. package/dist/render/scoped-css.d.ts.map +1 -0
  469. package/dist/render/scoped-css.js +102 -0
  470. package/dist/render/scoped-css.js.map +1 -0
  471. package/dist/render/shell-selection.d.ts +70 -0
  472. package/dist/render/shell-selection.d.ts.map +1 -0
  473. package/dist/render/shell-selection.js +117 -0
  474. package/dist/render/shell-selection.js.map +1 -0
  475. package/dist/render/states-css.d.ts +33 -0
  476. package/dist/render/states-css.d.ts.map +1 -0
  477. package/dist/render/states-css.js +63 -0
  478. package/dist/render/states-css.js.map +1 -0
  479. package/dist/render/surface-data-context.d.ts +19 -0
  480. package/dist/render/surface-data-context.d.ts.map +1 -0
  481. package/dist/render/surface-data-context.js +21 -0
  482. package/dist/render/surface-data-context.js.map +1 -0
  483. package/dist/render/surface-event-bus.d.ts +20 -0
  484. package/dist/render/surface-event-bus.d.ts.map +1 -0
  485. package/dist/render/surface-event-bus.js +68 -0
  486. package/dist/render/surface-event-bus.js.map +1 -0
  487. package/dist/render/surface-event-context.d.ts +12 -0
  488. package/dist/render/surface-event-context.d.ts.map +1 -0
  489. package/dist/render/surface-event-context.js +12 -0
  490. package/dist/render/surface-event-context.js.map +1 -0
  491. package/dist/render/surface-id-context.d.ts +9 -0
  492. package/dist/render/surface-id-context.d.ts.map +1 -0
  493. package/dist/render/surface-id-context.js +9 -0
  494. package/dist/render/surface-id-context.js.map +1 -0
  495. package/dist/render/theme-utils.d.ts +15 -0
  496. package/dist/render/theme-utils.d.ts.map +1 -0
  497. package/dist/render/theme-utils.js +15 -0
  498. package/dist/render/theme-utils.js.map +1 -0
  499. package/dist/render/types.d.ts +283 -0
  500. package/dist/render/types.d.ts.map +1 -0
  501. package/dist/render/types.js +9 -0
  502. package/dist/render/types.js.map +1 -0
  503. package/dist/render/visibility-css.d.ts +43 -0
  504. package/dist/render/visibility-css.d.ts.map +1 -0
  505. package/dist/render/visibility-css.js +119 -0
  506. package/dist/render/visibility-css.js.map +1 -0
  507. package/dist/render/width-scope.d.ts +35 -0
  508. package/dist/render/width-scope.d.ts.map +1 -0
  509. package/dist/render/width-scope.js +44 -0
  510. package/dist/render/width-scope.js.map +1 -0
  511. package/dist/render/write-only-sources.d.ts +34 -0
  512. package/dist/render/write-only-sources.d.ts.map +1 -0
  513. package/dist/render/write-only-sources.js +99 -0
  514. package/dist/render/write-only-sources.js.map +1 -0
  515. package/dist/routing/index.d.ts +15 -0
  516. package/dist/routing/index.d.ts.map +1 -0
  517. package/dist/routing/index.js +15 -0
  518. package/dist/routing/index.js.map +1 -0
  519. package/dist/routing/router.d.ts +43 -0
  520. package/dist/routing/router.d.ts.map +1 -0
  521. package/dist/routing/router.js +218 -0
  522. package/dist/routing/router.js.map +1 -0
  523. package/dist/routing/types.d.ts +125 -0
  524. package/dist/routing/types.d.ts.map +1 -0
  525. package/dist/routing/types.js +9 -0
  526. package/dist/routing/types.js.map +1 -0
  527. package/dist/seo/generator.d.ts +40 -0
  528. package/dist/seo/generator.d.ts.map +1 -0
  529. package/dist/seo/generator.js +236 -0
  530. package/dist/seo/generator.js.map +1 -0
  531. package/dist/seo/index.d.ts +15 -0
  532. package/dist/seo/index.d.ts.map +1 -0
  533. package/dist/seo/index.js +15 -0
  534. package/dist/seo/index.js.map +1 -0
  535. package/dist/seo/types.d.ts +182 -0
  536. package/dist/seo/types.d.ts.map +1 -0
  537. package/dist/seo/types.js +9 -0
  538. package/dist/seo/types.js.map +1 -0
  539. package/dist/state/index.d.ts +16 -0
  540. package/dist/state/index.d.ts.map +1 -0
  541. package/dist/state/index.js +16 -0
  542. package/dist/state/index.js.map +1 -0
  543. package/dist/state/manager.d.ts +34 -0
  544. package/dist/state/manager.d.ts.map +1 -0
  545. package/dist/state/manager.js +81 -0
  546. package/dist/state/manager.js.map +1 -0
  547. package/dist/state/store.d.ts +41 -0
  548. package/dist/state/store.d.ts.map +1 -0
  549. package/dist/state/store.js +145 -0
  550. package/dist/state/store.js.map +1 -0
  551. package/dist/state/types.d.ts +108 -0
  552. package/dist/state/types.d.ts.map +1 -0
  553. package/dist/state/types.js +9 -0
  554. package/dist/state/types.js.map +1 -0
  555. package/dist/surface/expression.d.ts +66 -0
  556. package/dist/surface/expression.d.ts.map +1 -0
  557. package/dist/surface/expression.js +179 -0
  558. package/dist/surface/expression.js.map +1 -0
  559. package/dist/surface/index.d.ts +33 -0
  560. package/dist/surface/index.d.ts.map +1 -0
  561. package/dist/surface/index.js +25 -0
  562. package/dist/surface/index.js.map +1 -0
  563. package/dist/surface/interpreter.d.ts +97 -0
  564. package/dist/surface/interpreter.d.ts.map +1 -0
  565. package/dist/surface/interpreter.js +231 -0
  566. package/dist/surface/interpreter.js.map +1 -0
  567. package/dist/surface/layout.d.ts +55 -0
  568. package/dist/surface/layout.d.ts.map +1 -0
  569. package/dist/surface/layout.js +288 -0
  570. package/dist/surface/layout.js.map +1 -0
  571. package/dist/surface/output.d.ts +91 -0
  572. package/dist/surface/output.d.ts.map +1 -0
  573. package/dist/surface/output.js +104 -0
  574. package/dist/surface/output.js.map +1 -0
  575. package/dist/surface/primitives.d.ts +181 -0
  576. package/dist/surface/primitives.d.ts.map +1 -0
  577. package/dist/surface/primitives.js +339 -0
  578. package/dist/surface/primitives.js.map +1 -0
  579. package/dist/surface/renderer.d.ts +97 -0
  580. package/dist/surface/renderer.d.ts.map +1 -0
  581. package/dist/surface/renderer.js +190 -0
  582. package/dist/surface/renderer.js.map +1 -0
  583. package/dist/surface/schemas.d.ts +182 -0
  584. package/dist/surface/schemas.d.ts.map +1 -0
  585. package/dist/surface/schemas.js +142 -0
  586. package/dist/surface/schemas.js.map +1 -0
  587. package/dist/surface/transforms.d.ts +145 -0
  588. package/dist/surface/transforms.d.ts.map +1 -0
  589. package/dist/surface/transforms.js +120 -0
  590. package/dist/surface/transforms.js.map +1 -0
  591. package/dist/surface/types.d.ts +161 -0
  592. package/dist/surface/types.d.ts.map +1 -0
  593. package/dist/surface/types.js +51 -0
  594. package/dist/surface/types.js.map +1 -0
  595. package/dist/surface/validation.d.ts +124 -0
  596. package/dist/surface/validation.d.ts.map +1 -0
  597. package/dist/surface/validation.js +147 -0
  598. package/dist/surface/validation.js.map +1 -0
  599. package/dist/validator.d.ts +56 -0
  600. package/dist/validator.d.ts.map +1 -0
  601. package/dist/validator.js +100 -0
  602. package/dist/validator.js.map +1 -0
  603. package/package.json +105 -3
@@ -0,0 +1,787 @@
1
+ /**
2
+ * Expression Evaluator for Data Binding
3
+ *
4
+ * Enhanced expression evaluation for data binding in surfaces
5
+ *
6
+ * This module extends the base expression evaluator with:
7
+ * - Arithmetic operations (+, -, *, /, %)
8
+ * - Data/state/params context separation
9
+ * - Dependency extraction for reactive updates
10
+ * - Safe null-coalescing operators
11
+ *
12
+ * @module @pwfabric/runtime/binding/expression
13
+ */
14
+ // ============================================================
15
+ // PATH RESOLUTION
16
+ // ============================================================
17
+ /**
18
+ * Read one named property off a value, stepping into a list of one record.
19
+ *
20
+ * A LIST SOURCE ALWAYS BINDS AS A LIST (DataBoundSurfaceRenderer): a `rest`,
21
+ * `entity` or `graphql` source answering with ONE object is bound as `[obj]`,
22
+ * so `{{src[0].field}}` and `{{src.length}}` behave the same whatever the
23
+ * endpoint returned. But a detail page is authored as `{{product.title}}`, and
24
+ * a property read on an array finds nothing — such a page would render blank
25
+ * (`{{rows.name}}` → empty while `{{rows[0].name}}` → "banana").
26
+ *
27
+ * So: when the value is an array of EXACTLY ONE element and the array itself
28
+ * does not carry the key (not `length`, not an index, not an array method),
29
+ * the read continues into that one element. A list of two or more is a list —
30
+ * its `.title` stays undefined, as it always was. Both evaluators (this one
31
+ * and surface/expression) read properties through here, so a path means the
32
+ * same thing in a binding and in a block prop.
33
+ */
34
+ export function readProperty(target, key) {
35
+ if (target === null || target === undefined || typeof target !== 'object')
36
+ return undefined;
37
+ if (Array.isArray(target) && target.length === 1 && !(key in target)) {
38
+ const only = target[0];
39
+ return only !== null && typeof only === 'object'
40
+ ? only[key]
41
+ : undefined;
42
+ }
43
+ return target[key];
44
+ }
45
+ /**
46
+ * Resolve a dotted path in an object, handling nested properties and array indices
47
+ *
48
+ * @example
49
+ * resolvePath({ user: { name: 'John' } }, 'user.name') // 'John'
50
+ * resolvePath({ items: ['a', 'b'] }, 'items[0]') // 'a'
51
+ * resolvePath({ users: [{ name: 'John' }] }, 'users[0].name') // 'John'
52
+ */
53
+ export function resolvePath(obj, path) {
54
+ if (!path || typeof obj !== 'object' || obj === null) {
55
+ return undefined;
56
+ }
57
+ const parts = parsePath(path);
58
+ let current = obj;
59
+ for (const part of parts) {
60
+ if (current === null || current === undefined) {
61
+ return undefined;
62
+ }
63
+ if (part.type === 'property') {
64
+ if (typeof current === 'object') {
65
+ current = readProperty(current, part.key);
66
+ }
67
+ else {
68
+ return undefined;
69
+ }
70
+ }
71
+ else if (part.type === 'index') {
72
+ if (Array.isArray(current)) {
73
+ current = current[part.index];
74
+ }
75
+ else {
76
+ return undefined;
77
+ }
78
+ }
79
+ }
80
+ return current;
81
+ }
82
+ /**
83
+ * Parse a path string into segments
84
+ */
85
+ function parsePath(path) {
86
+ const segments = [];
87
+ // Match property names and array indices: foo, [0], foo[0], foo.bar[1].baz
88
+ //
89
+ // A HYPHEN is a name CHARACTER. With `\w+` it would be a boundary, and since
90
+ // source ids are hyphenated, `hero-stats.0.text` would split into FOUR
91
+ // segments (`hero`,`stats`,`0`,`text`) instead of three and never resolve.
92
+ // The sibling resolver (surface/expression.ts) accepts hyphenated ids too:
93
+ // its path regex is `/^[\w\-.[\]]+$/`.
94
+ const regex = /([\w-]+)|\[(\d+)\]/g;
95
+ let match;
96
+ while ((match = regex.exec(path)) !== null) {
97
+ if (match[1] !== undefined) {
98
+ // Property name
99
+ segments.push({ type: 'property', key: match[1] });
100
+ }
101
+ else if (match[2] !== undefined) {
102
+ // Array index
103
+ segments.push({ type: 'index', index: parseInt(match[2], 10) });
104
+ }
105
+ }
106
+ return segments;
107
+ }
108
+ const MULTI_OPS = ['===', '!==', '>=', '<=', '==', '!=', '&&', '||', '??'];
109
+ const SINGLE_OPS = new Set(['+', '-', '*', '/', '%', '>', '<', '!']);
110
+ /** A token after which a `-` is binary minus, not the sign of a number. */
111
+ function endsValue(t) {
112
+ if (!t)
113
+ return false;
114
+ if (t.type === 'number' || t.type === 'string' || t.type === 'literal' || t.type === 'identifier')
115
+ return true;
116
+ return (t.type === 'paren' && t.value === ')') || (t.type === 'bracket' && t.value === ']');
117
+ }
118
+ function tokenize(expr, opts) {
119
+ const tokens = [];
120
+ let i = 0;
121
+ const nameChar = /[\w$]/;
122
+ const readName = (allowLeadingDigit) => {
123
+ let name = '';
124
+ while (i < expr.length) {
125
+ const c = expr.charAt(i);
126
+ if (nameChar.test(c)) {
127
+ name += c;
128
+ i++;
129
+ continue;
130
+ }
131
+ // a hyphen joins two name characters (`hero-stats`) in hyphenNames mode
132
+ if (opts.hyphenNames &&
133
+ c === '-' &&
134
+ name.length > 0 &&
135
+ /[\w$]/.test(expr.charAt(i + 1))) {
136
+ name += c;
137
+ i++;
138
+ continue;
139
+ }
140
+ break;
141
+ }
142
+ if (!allowLeadingDigit && /^\d/.test(name))
143
+ throw new Error(`Unexpected number in name '${name}'`);
144
+ return name;
145
+ };
146
+ while (i < expr.length) {
147
+ const ch = expr.charAt(i);
148
+ if (/\s/.test(ch)) {
149
+ i++;
150
+ continue;
151
+ }
152
+ const prev = tokens[tokens.length - 1];
153
+ // A property name after a dot: digits (`items.0`) and keywords
154
+ // (`item.default`, `row.null`) are names here, never literals.
155
+ if (prev?.type === 'dot' && /[\w$]/.test(ch)) {
156
+ const name = readName(true);
157
+ tokens.push({ type: 'identifier', value: name, raw: name });
158
+ continue;
159
+ }
160
+ if (ch === "'" || ch === '"') {
161
+ const quote = ch;
162
+ let value = '';
163
+ i++;
164
+ let closed = false;
165
+ while (i < expr.length) {
166
+ const c = expr.charAt(i);
167
+ if (c === quote) {
168
+ closed = true;
169
+ break;
170
+ }
171
+ if (c === '\\' && i + 1 < expr.length) {
172
+ i++;
173
+ const e = expr.charAt(i);
174
+ value += e === 'n' ? '\n' : e === 't' ? '\t' : e;
175
+ }
176
+ else {
177
+ value += c;
178
+ }
179
+ i++;
180
+ }
181
+ if (!closed)
182
+ throw new Error('Unterminated string literal');
183
+ i++;
184
+ tokens.push({ type: 'string', value, raw: `${quote}${value}${quote}` });
185
+ continue;
186
+ }
187
+ // Numbers. A leading `-` is a sign only where a value cannot end —
188
+ // `5-3` is subtraction, `-3` and `a * -3` are negative literals.
189
+ if (/\d/.test(ch) || (ch === '-' && /\d/.test(expr.charAt(i + 1)) && !endsValue(prev))) {
190
+ let num = '';
191
+ if (ch === '-') {
192
+ num = '-';
193
+ i++;
194
+ }
195
+ while (i < expr.length && /\d/.test(expr.charAt(i)))
196
+ num += expr.charAt(i++);
197
+ if (expr.charAt(i) === '.' && /\d/.test(expr.charAt(i + 1))) {
198
+ num += expr.charAt(i++);
199
+ while (i < expr.length && /\d/.test(expr.charAt(i)))
200
+ num += expr.charAt(i++);
201
+ }
202
+ tokens.push({ type: 'number', value: parseFloat(num), raw: num });
203
+ continue;
204
+ }
205
+ if (/[a-zA-Z_$]/.test(ch)) {
206
+ const name = readName(false);
207
+ if (name === 'true')
208
+ tokens.push({ type: 'literal', value: true, raw: name });
209
+ else if (name === 'false')
210
+ tokens.push({ type: 'literal', value: false, raw: name });
211
+ else if (name === 'null')
212
+ tokens.push({ type: 'literal', value: null, raw: name });
213
+ else if (name === 'undefined')
214
+ tokens.push({ type: 'literal', value: opts.undefinedAsNull ? null : undefined, raw: name });
215
+ else
216
+ tokens.push({ type: 'identifier', value: name, raw: name });
217
+ continue;
218
+ }
219
+ const multi = MULTI_OPS.find((op) => expr.startsWith(op, i));
220
+ if (multi) {
221
+ tokens.push({ type: 'operator', value: multi, raw: multi });
222
+ i += multi.length;
223
+ continue;
224
+ }
225
+ if (SINGLE_OPS.has(ch))
226
+ tokens.push({ type: 'operator', value: ch, raw: ch });
227
+ else if (ch === '(' || ch === ')')
228
+ tokens.push({ type: 'paren', value: ch, raw: ch });
229
+ else if (ch === '[' || ch === ']')
230
+ tokens.push({ type: 'bracket', value: ch, raw: ch });
231
+ else if (ch === '.')
232
+ tokens.push({ type: 'dot', value: ch, raw: ch });
233
+ else if (ch === ',')
234
+ tokens.push({ type: 'comma', value: ch, raw: ch });
235
+ else if (ch === '?')
236
+ tokens.push({ type: 'question', value: ch, raw: ch });
237
+ else if (ch === ':')
238
+ tokens.push({ type: 'colon', value: ch, raw: ch });
239
+ else
240
+ throw new Error(`Unexpected character '${ch}' at ${i}`);
241
+ i++;
242
+ }
243
+ return tokens;
244
+ }
245
+ const BINARY_LEVELS = [
246
+ ['||'],
247
+ ['&&'],
248
+ ['??'],
249
+ ['===', '!==', '==', '!='],
250
+ ['>', '<', '>=', '<='],
251
+ ['+', '-'],
252
+ ['*', '/', '%'],
253
+ ];
254
+ function parse(tokens) {
255
+ let pos = 0;
256
+ const peek = () => tokens[pos];
257
+ const is = (type, value) => {
258
+ const t = tokens[pos];
259
+ return t !== undefined && t.type === type && (value === undefined || t.value === value);
260
+ };
261
+ const expect = (type, value, what) => {
262
+ if (!is(type, value))
263
+ throw new Error(`Expected ${what}`);
264
+ pos++;
265
+ };
266
+ const parseArgs = (close, closeType) => {
267
+ const args = [];
268
+ if (is(closeType, close)) {
269
+ pos++;
270
+ return args;
271
+ }
272
+ for (;;) {
273
+ args.push(parseTernary());
274
+ if (is('comma')) {
275
+ pos++;
276
+ continue;
277
+ }
278
+ expect(closeType, close, `'${close}'`);
279
+ return args;
280
+ }
281
+ };
282
+ function parseTernary() {
283
+ const test = parseBinary(0);
284
+ if (!is('question'))
285
+ return test;
286
+ pos++;
287
+ const then = parseTernary();
288
+ expect('colon', ':', "':' in ternary expression");
289
+ return { k: 'cond', test, then, else: parseTernary() };
290
+ }
291
+ function parseBinary(level) {
292
+ const ops = BINARY_LEVELS[level];
293
+ if (!ops)
294
+ return parseUnary();
295
+ let left = parseBinary(level + 1);
296
+ for (;;) {
297
+ const t = peek();
298
+ if (!t || t.type !== 'operator' || !ops.includes(t.value))
299
+ return left;
300
+ pos++;
301
+ left = { k: 'binary', op: t.value, l: left, r: parseBinary(level + 1) };
302
+ }
303
+ }
304
+ function parseUnary() {
305
+ if (is('operator', '!') || is('operator', '-') || is('operator', '+')) {
306
+ const op = tokens[pos++].value;
307
+ return { k: 'unary', op, arg: parseUnary() };
308
+ }
309
+ return parsePostfix();
310
+ }
311
+ function parsePostfix() {
312
+ let node = parsePrimary();
313
+ for (;;) {
314
+ if (is('dot')) {
315
+ pos++;
316
+ const t = peek();
317
+ if (!t || t.type !== 'identifier')
318
+ throw new Error('Expected property name after .');
319
+ pos++;
320
+ const name = t.value;
321
+ if (is('paren', '(')) {
322
+ pos++;
323
+ node = { k: 'method', obj: node, name, args: parseArgs(')', 'paren') };
324
+ }
325
+ else {
326
+ node = { k: 'member', obj: node, prop: name };
327
+ }
328
+ }
329
+ else if (is('bracket', '[')) {
330
+ pos++;
331
+ const index = parseTernary();
332
+ expect('bracket', ']', "']'");
333
+ node = { k: 'index', obj: node, index };
334
+ }
335
+ else if (is('paren', '(')) {
336
+ throw new Error('Only helpers and safe methods can be called');
337
+ }
338
+ else {
339
+ return node;
340
+ }
341
+ }
342
+ }
343
+ function parsePrimary() {
344
+ const t = peek();
345
+ if (!t)
346
+ throw new Error('Unexpected end of expression');
347
+ if (t.type === 'number' || t.type === 'string' || t.type === 'literal') {
348
+ pos++;
349
+ return { k: 'lit', v: t.value };
350
+ }
351
+ if (t.type === 'identifier') {
352
+ pos++;
353
+ const name = t.value;
354
+ if (is('paren', '(')) {
355
+ pos++;
356
+ return { k: 'call', name, args: parseArgs(')', 'paren') };
357
+ }
358
+ return { k: 'name', name };
359
+ }
360
+ if (is('paren', '(')) {
361
+ pos++;
362
+ const inner = parseTernary();
363
+ expect('paren', ')', "')'");
364
+ return inner;
365
+ }
366
+ if (is('bracket', '[')) {
367
+ pos++;
368
+ return { k: 'array', items: parseArgs(']', 'bracket') };
369
+ }
370
+ throw new Error(`Unexpected token '${t.raw}'`);
371
+ }
372
+ const root = parseTernary();
373
+ if (pos < tokens.length)
374
+ throw new Error(`Unexpected token '${tokens[pos].raw}'`);
375
+ return root;
376
+ }
377
+ /**
378
+ * Parse once, evaluate many times. Block props are re-resolved on every state
379
+ * change, and the same few hundred template strings come through each time.
380
+ */
381
+ const AST_CACHE_LIMIT = 2000;
382
+ const astCache = new Map();
383
+ function parseCached(expr, opts) {
384
+ const key = `${opts.hyphenNames ? 'h' : '-'}${opts.undefinedAsNull ? 'n' : '-'}${expr}`;
385
+ let hit = astCache.get(key);
386
+ if (hit === undefined) {
387
+ try {
388
+ hit = parse(tokenize(expr, opts));
389
+ }
390
+ catch (e) {
391
+ hit = e instanceof Error ? e : new Error(String(e));
392
+ }
393
+ if (astCache.size >= AST_CACHE_LIMIT)
394
+ astCache.clear();
395
+ astCache.set(key, hit);
396
+ }
397
+ if (hit instanceof Error)
398
+ throw hit;
399
+ return hit;
400
+ }
401
+ /**
402
+ * Methods that may be called on a value. Pure, allocation-bounded, and
403
+ * nothing that reaches a constructor, a prototype or a function: a template
404
+ * is authored by a model and rendered in a visitor's browser.
405
+ */
406
+ const STRING_METHODS = new Set([
407
+ 'toLowerCase', 'toUpperCase', 'trim', 'trimStart', 'trimEnd', 'includes', 'startsWith', 'endsWith',
408
+ 'indexOf', 'lastIndexOf', 'slice', 'substring', 'padStart', 'padEnd', 'split', 'replace',
409
+ 'replaceAll', 'charAt', 'at', 'concat', 'repeat', 'toString', 'localeCompare',
410
+ ]);
411
+ const ARRAY_METHODS = new Set(['includes', 'indexOf', 'lastIndexOf', 'join', 'slice', 'at', 'concat']);
412
+ const NUMBER_METHODS = new Set(['toFixed', 'toPrecision', 'toString', 'toLocaleString']);
413
+ function callMethod(target, name, args) {
414
+ if (target === null || target === undefined)
415
+ return undefined;
416
+ let allowed = false;
417
+ if (typeof target === 'string')
418
+ allowed = STRING_METHODS.has(name);
419
+ else if (Array.isArray(target))
420
+ allowed = ARRAY_METHODS.has(name);
421
+ else if (typeof target === 'number')
422
+ allowed = NUMBER_METHODS.has(name);
423
+ if (!allowed)
424
+ throw new Error(`Method '${name}' is not supported`);
425
+ // A `repeat`/`padStart` count from data must not allocate without bound.
426
+ if ((name === 'repeat' || name === 'padStart' || name === 'padEnd') && Number(args[0]) > 10_000) {
427
+ throw new Error(`Method '${name}' argument too large`);
428
+ }
429
+ const fn = target[name];
430
+ return fn.apply(target, args);
431
+ }
432
+ function readMember(target, prop) {
433
+ if (typeof target === 'string')
434
+ return prop === 'length' ? target.length : undefined;
435
+ if (target !== null && target !== undefined && typeof target === 'object')
436
+ return readProperty(target, prop);
437
+ return undefined;
438
+ }
439
+ function evalNode(node, scope) {
440
+ switch (node.k) {
441
+ case 'lit':
442
+ return node.v;
443
+ case 'name':
444
+ return scope.lookup(node.name);
445
+ case 'member':
446
+ return readMember(evalNode(node.obj, scope), node.prop);
447
+ case 'index': {
448
+ const target = evalNode(node.obj, scope);
449
+ const index = evalNode(node.index, scope);
450
+ if (target === null || target === undefined)
451
+ return undefined;
452
+ if (Array.isArray(target))
453
+ return target[index];
454
+ if (typeof target === 'object')
455
+ return target[String(index)];
456
+ return undefined;
457
+ }
458
+ case 'call': {
459
+ const fn = scope.helper(node.name);
460
+ if (typeof fn !== 'function')
461
+ throw new Error(`Unknown helper: ${node.name}`);
462
+ return fn(...node.args.map((a) => evalNode(a, scope)));
463
+ }
464
+ case 'method':
465
+ return callMethod(evalNode(node.obj, scope), node.name, node.args.map((a) => evalNode(a, scope)));
466
+ case 'unary': {
467
+ const v = evalNode(node.arg, scope);
468
+ if (node.op === '!')
469
+ return !v;
470
+ if (node.op === '-')
471
+ return -v;
472
+ return +v;
473
+ }
474
+ case 'cond':
475
+ return evalNode(node.test, scope) ? evalNode(node.then, scope) : evalNode(node.else, scope);
476
+ case 'array':
477
+ return node.items.map((n) => evalNode(n, scope));
478
+ case 'binary': {
479
+ // short-circuiting operators first — the right side may never run
480
+ if (node.op === '&&') {
481
+ const l = evalNode(node.l, scope);
482
+ return l ? evalNode(node.r, scope) : l;
483
+ }
484
+ if (node.op === '||') {
485
+ const l = evalNode(node.l, scope);
486
+ return l ? l : evalNode(node.r, scope);
487
+ }
488
+ if (node.op === '??') {
489
+ const l = evalNode(node.l, scope);
490
+ return l ?? evalNode(node.r, scope);
491
+ }
492
+ const l = evalNode(node.l, scope);
493
+ const r = evalNode(node.r, scope);
494
+ switch (node.op) {
495
+ case '===': return l === r;
496
+ case '!==': return l !== r;
497
+ case '==': return l == r;
498
+ case '!=': return l != r;
499
+ case '>': return l > r;
500
+ case '<': return l < r;
501
+ case '>=': return l >= r;
502
+ case '<=': return l <= r;
503
+ case '+':
504
+ return typeof l === 'string' || typeof r === 'string'
505
+ ? String(l) + String(r)
506
+ : l + r;
507
+ case '-': return l - r;
508
+ case '*': return l * r;
509
+ case '/': return l / r;
510
+ case '%': return l % r;
511
+ }
512
+ throw new Error(`Unknown operator ${node.op}`);
513
+ }
514
+ }
515
+ }
516
+ /**
517
+ * Evaluate one expression (the text between `{{` and `}}`) against a scope.
518
+ * Throws on a syntax error, an unknown helper or an unsupported method — the
519
+ * two public evaluators turn that into `{ success: false }`.
520
+ */
521
+ export function evaluateWithScope(expression, scope, opts = {}) {
522
+ const trimmed = expression.trim();
523
+ if (!trimmed)
524
+ return undefined;
525
+ return evalNode(parseCached(trimmed, opts), scope);
526
+ }
527
+ // ============================================================
528
+ // EXPRESSION EVALUATOR IMPLEMENTATION
529
+ // ============================================================
530
+ /**
531
+ * Evaluate an expression with full context support
532
+ */
533
+ export function evaluateExpression(expression, context) {
534
+ try {
535
+ const helpers = context.helpers;
536
+ const scope = {
537
+ lookup(name) {
538
+ if (name === 'data')
539
+ return context.data;
540
+ if (name === 'state')
541
+ return context.state;
542
+ if (name === 'params')
543
+ return context.params;
544
+ // A helper named bare (without a call) has always resolved to the
545
+ // function itself here; kept.
546
+ if (helpers && Object.prototype.hasOwnProperty.call(helpers, name))
547
+ return helpers[name];
548
+ // Shorthand access. Priority: params > state > data (most specific first)
549
+ if (name in context.params)
550
+ return context.params[name];
551
+ if (name in context.state)
552
+ return context.state[name];
553
+ if (name in context.data)
554
+ return context.data[name];
555
+ return undefined;
556
+ },
557
+ helper: (name) => (helpers && Object.prototype.hasOwnProperty.call(helpers, name) ? helpers[name] : undefined),
558
+ };
559
+ return { success: true, value: evaluateWithScope(expression, scope, { undefinedAsNull: true }) };
560
+ }
561
+ catch (e) {
562
+ return { success: false, error: `Expression error: ${e}` };
563
+ }
564
+ }
565
+ // ============================================================
566
+ // DEPENDENCY EXTRACTION
567
+ // ============================================================
568
+ /**
569
+ * Extract dependencies from an expression for reactive updates
570
+ */
571
+ export function extractDependencies(expression) {
572
+ const dependencies = [];
573
+ const seen = new Set();
574
+ // Match patterns like: data.foo.bar, state.count, params.id
575
+ // Also match shorthand: foo.bar (when referring to data/state/params root)
576
+ const patterns = [
577
+ /\bdata\.(\w+(?:\.\w+|\[\d+\])*)/g,
578
+ /\bstate\.(\w+(?:\.\w+|\[\d+\])*)/g,
579
+ /\bparams\.(\w+(?:\.\w+|\[\d+\])*)/g,
580
+ ];
581
+ const sources = ['data', 'state', 'params'];
582
+ for (let i = 0; i < patterns.length; i++) {
583
+ const pattern = patterns[i];
584
+ const source = sources[i];
585
+ if (!pattern || !source)
586
+ continue;
587
+ let match;
588
+ while ((match = pattern.exec(expression)) !== null) {
589
+ const path = match[1];
590
+ if (path === undefined)
591
+ continue;
592
+ const key = `${source}.${path}`;
593
+ if (!seen.has(key)) {
594
+ seen.add(key);
595
+ dependencies.push({ source, path });
596
+ }
597
+ }
598
+ }
599
+ return dependencies;
600
+ }
601
+ // ============================================================
602
+ // INTERPOLATION
603
+ // ============================================================
604
+ /**
605
+ * Check if a value contains expression syntax
606
+ */
607
+ export function isExpression(value) {
608
+ if (typeof value !== 'string')
609
+ return false;
610
+ return /\{\{.+?\}\}/.test(value);
611
+ }
612
+ /**
613
+ * Interpolate expressions within a template string
614
+ *
615
+ * @example
616
+ * interpolate('Hello, {{user.name}}!', context) // 'Hello, John!'
617
+ * interpolate('Total: {{price * quantity}}', context) // 'Total: 100'
618
+ */
619
+ export function interpolate(template, context) {
620
+ const pattern = /\{\{(.+?)\}\}/g;
621
+ return template.replace(pattern, (_, expr) => {
622
+ const result = evaluateExpression(expr.trim(), context);
623
+ if (result.success) {
624
+ return String(result.value ?? '');
625
+ }
626
+ return '';
627
+ });
628
+ }
629
+ // ============================================================
630
+ // DEFAULT HELPERS
631
+ // ============================================================
632
+ /**
633
+ * Default helper functions for expressions
634
+ */
635
+ export const DEFAULT_BINDING_HELPERS = {
636
+ // String helpers
637
+ upper: (s) => String(s).toUpperCase(),
638
+ lower: (s) => String(s).toLowerCase(),
639
+ trim: (s) => String(s).trim(),
640
+ capitalize: (s) => {
641
+ const str = String(s);
642
+ return str.charAt(0).toUpperCase() + str.slice(1);
643
+ },
644
+ concat: (...args) => args.map(String).join(''),
645
+ // Number helpers
646
+ round: (n, decimals) => {
647
+ const num = Number(n);
648
+ const d = Number(decimals ?? 0);
649
+ return Math.round(num * Math.pow(10, d)) / Math.pow(10, d);
650
+ },
651
+ floor: (n) => Math.floor(Number(n)),
652
+ ceil: (n) => Math.ceil(Number(n)),
653
+ abs: (n) => Math.abs(Number(n)),
654
+ min: (...args) => Math.min(...args.map(Number)),
655
+ max: (...args) => Math.max(...args.map(Number)),
656
+ /**
657
+ * How many pages `total` rows fill at `size` per page — `ceil(total / size)`,
658
+ * but SAFE: a missing, non-numeric, zero or negative total or size gives 0,
659
+ * never `NaN` or `Infinity` (the envelope is absent until the first fetch
660
+ * lands). Pair with `__meta.<source>.total` on a `returns` source:
661
+ * `{{pages(__meta.products.total, 20)}}`. Wrap in `max(1, …)` for a pager
662
+ * that should read "1 / 1" on an empty list.
663
+ */
664
+ pages: (total, size) => {
665
+ const t = Number(total);
666
+ const s = Number(size);
667
+ if (!Number.isFinite(t) || !Number.isFinite(s) || t <= 0 || s <= 0)
668
+ return 0;
669
+ return Math.ceil(t / s);
670
+ },
671
+ // Aggregate helpers — one data source, several KPI figures. Without these a
672
+ // KPI strip needed one source (one fetch) per number. Filtering stays the
673
+ // data layer's job (EntityQuery.filter); these only fold what is already
674
+ // fetched.
675
+ sumBy: (items, field) => {
676
+ if (!Array.isArray(items))
677
+ return 0;
678
+ const f = field === undefined ? undefined : String(field);
679
+ return items.reduce((acc, it) => {
680
+ const v = f === undefined ? it : it?.[f];
681
+ const n = Number(v);
682
+ return Number.isFinite(n) ? acc + n : acc;
683
+ }, 0);
684
+ },
685
+ groupCount: (items, field) => {
686
+ const out = {};
687
+ if (!Array.isArray(items))
688
+ return out;
689
+ const f = String(field);
690
+ for (const it of items) {
691
+ const v = it?.[f];
692
+ const key = v === null || v === undefined || v === '' ? 'unknown' : String(v);
693
+ out[key] = (out[key] ?? 0) + 1;
694
+ }
695
+ return out;
696
+ },
697
+ // Array helpers
698
+ length: (arr) => (Array.isArray(arr) ? arr.length : String(arr).length),
699
+ first: (arr) => (Array.isArray(arr) ? arr[0] : undefined),
700
+ last: (arr) => (Array.isArray(arr) ? arr[arr.length - 1] : undefined),
701
+ join: (arr, sep) => Array.isArray(arr) ? arr.join(String(sep ?? ',')) : String(arr),
702
+ includes: (arr, item) => Array.isArray(arr) ? arr.includes(item) : String(arr).includes(String(item)),
703
+ slice: (arr, start, end) => {
704
+ if (Array.isArray(arr)) {
705
+ return arr.slice(start !== undefined ? Number(start) : undefined, end !== undefined ? Number(end) : undefined);
706
+ }
707
+ return String(arr).slice(start !== undefined ? Number(start) : undefined, end !== undefined ? Number(end) : undefined);
708
+ },
709
+ // Type checks
710
+ isEmpty: (v) => v === null ||
711
+ v === undefined ||
712
+ v === '' ||
713
+ (Array.isArray(v) && v.length === 0) ||
714
+ (typeof v === 'object' && Object.keys(v).length === 0),
715
+ isNotEmpty: (v) => v !== null && v !== undefined && v !== '' && !(Array.isArray(v) && v.length === 0),
716
+ isArray: (v) => Array.isArray(v),
717
+ isString: (v) => typeof v === 'string',
718
+ isNumber: (v) => typeof v === 'number' && !isNaN(v),
719
+ isBoolean: (v) => typeof v === 'boolean',
720
+ isNull: (v) => v === null || v === undefined,
721
+ // Object helpers
722
+ keys: (obj) => (typeof obj === 'object' && obj !== null ? Object.keys(obj) : []),
723
+ values: (obj) => (typeof obj === 'object' && obj !== null ? Object.values(obj) : []),
724
+ // Formatting helpers
725
+ json: (v) => JSON.stringify(v),
726
+ /**
727
+ * Today's date in the visitor's time zone, as `YYYY-MM-DD`.
728
+ * The shape date fields are stored in, so it compares as a string:
729
+ * `{{event.date >= today()}}` for "upcoming", `today(-7)` for a week ago.
730
+ * The optional argument shifts by whole days. Before this an "upcoming"
731
+ * filter had nothing to compare against and a page hard-coded a date.
732
+ */
733
+ today: (offsetDays) => {
734
+ const d = new Date();
735
+ const shift = Number(offsetDays ?? 0);
736
+ if (Number.isFinite(shift) && shift !== 0)
737
+ d.setDate(d.getDate() + Math.trunc(shift));
738
+ const mm = String(d.getMonth() + 1).padStart(2, '0');
739
+ const dd = String(d.getDate()).padStart(2, '0');
740
+ return `${d.getFullYear()}-${mm}-${dd}`;
741
+ },
742
+ date: (v) => new Date(v).toLocaleDateString(),
743
+ time: (v) => new Date(v).toLocaleTimeString(),
744
+ datetime: (v) => new Date(v).toLocaleString(),
745
+ currency: (v, currency, locale) => {
746
+ const num = Number(v);
747
+ return new Intl.NumberFormat(String(locale ?? 'en-US'), {
748
+ style: 'currency',
749
+ currency: String(currency ?? 'USD'),
750
+ }).format(num);
751
+ },
752
+ percent: (v, decimals) => {
753
+ const num = Number(v);
754
+ const d = Number(decimals ?? 0);
755
+ return `${(num * 100).toFixed(d)}%`;
756
+ },
757
+ };
758
+ // ============================================================
759
+ // EXPRESSION EVALUATOR FACTORY
760
+ // ============================================================
761
+ /**
762
+ * Create an expression evaluator with context and helpers
763
+ */
764
+ export function createExpressionEvaluator(additionalHelpers) {
765
+ const helpers = { ...DEFAULT_BINDING_HELPERS, ...additionalHelpers };
766
+ return {
767
+ evaluate(expression, context) {
768
+ const result = evaluateExpression(expression, {
769
+ ...context,
770
+ helpers: { ...helpers, ...context.helpers },
771
+ });
772
+ if (result.success) {
773
+ return result.value;
774
+ }
775
+ throw new Error(result.error);
776
+ },
777
+ isExpression,
778
+ extractDependencies,
779
+ interpolate(template, context) {
780
+ return interpolate(template, {
781
+ ...context,
782
+ helpers: { ...helpers, ...context.helpers },
783
+ });
784
+ },
785
+ };
786
+ }
787
+ //# sourceMappingURL=expression.js.map