@studiometa/js-toolkit 4.0.0-alpha.1 → 4.0.0-alpha.3

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 (455) hide show
  1. package/README.md +10 -0
  2. package/dist/Base.d.ts +0 -2
  3. package/dist/Base.js +1 -2
  4. package/dist/Base.js.map +1 -1
  5. package/dist/attribute-namespaces.d.ts +0 -2
  6. package/dist/attribute-namespaces.js +1 -2
  7. package/dist/attributes.d.ts +0 -2
  8. package/dist/attributes.js +1 -2
  9. package/dist/children-watchers.d.ts +0 -2
  10. package/dist/children-watchers.js +1 -2
  11. package/dist/component-brand.d.ts +0 -2
  12. package/dist/component-brand.js +1 -2
  13. package/dist/component-declarations.d.ts +0 -2
  14. package/dist/component-declarations.js +1 -2
  15. package/dist/context-subscription.d.ts +0 -2
  16. package/dist/context-subscription.js +1 -2
  17. package/dist/context.d.ts +0 -2
  18. package/dist/context.js +1 -2
  19. package/dist/decorators.d.ts +0 -2
  20. package/dist/decorators.js +1 -2
  21. package/dist/diagnostic-contract.d.ts +0 -2
  22. package/dist/diagnostic-contract.js +1 -2
  23. package/dist/diagnostics.d.ts +0 -2
  24. package/dist/diagnostics.js +1 -2
  25. package/dist/document-order.d.ts +0 -2
  26. package/dist/document-order.js +1 -2
  27. package/dist/dom-mutations.d.ts +0 -2
  28. package/dist/dom-mutations.js +1 -2
  29. package/dist/events.d.ts +0 -2
  30. package/dist/events.js +1 -2
  31. package/dist/group.d.ts +0 -2
  32. package/dist/group.js +1 -2
  33. package/dist/instances.d.ts +0 -2
  34. package/dist/instances.js +1 -2
  35. package/dist/manifest.d.ts +0 -2
  36. package/dist/manifest.js +1 -2
  37. package/dist/mount-strategies.d.ts +0 -2
  38. package/dist/mount-strategies.js +1 -2
  39. package/dist/negotiated-events.d.ts +0 -2
  40. package/dist/negotiated-events.js +1 -2
  41. package/dist/protocol-symbols.d.ts +0 -2
  42. package/dist/protocol-symbols.js +1 -2
  43. package/dist/registry.d.ts +0 -2
  44. package/dist/registry.js +1 -2
  45. package/dist/responsive-options.d.ts +0 -2
  46. package/dist/responsive-options.js +1 -2
  47. package/dist/scheduler.d.ts +0 -2
  48. package/dist/scheduler.js +1 -2
  49. package/dist/scheduler.js.map +1 -1
  50. package/dist/services/breakpoint.d.ts +0 -2
  51. package/dist/services/breakpoint.js +1 -2
  52. package/dist/services/drag.d.ts +0 -2
  53. package/dist/services/drag.js +1 -2
  54. package/dist/services/in-view.d.ts +0 -2
  55. package/dist/services/in-view.js +1 -2
  56. package/dist/services/key.d.ts +0 -2
  57. package/dist/services/key.js +1 -2
  58. package/dist/services/media.d.ts +0 -2
  59. package/dist/services/media.js +1 -2
  60. package/dist/services/mixin.d.ts +0 -2
  61. package/dist/services/mixin.js +1 -2
  62. package/dist/services/mutation.d.ts +0 -2
  63. package/dist/services/mutation.js +1 -2
  64. package/dist/services/pointer.d.ts +0 -2
  65. package/dist/services/pointer.js +1 -2
  66. package/dist/services/raf.d.ts +0 -2
  67. package/dist/services/raf.js +1 -2
  68. package/dist/services/resize.d.ts +0 -2
  69. package/dist/services/resize.js +1 -2
  70. package/dist/services/scroll-progress-offset.d.ts +0 -2
  71. package/dist/services/scroll-progress-offset.js +1 -2
  72. package/dist/services/scroll-progress.d.ts +0 -2
  73. package/dist/services/scroll-progress.js +1 -2
  74. package/dist/services/scroll.d.ts +0 -2
  75. package/dist/services/scroll.js +1 -2
  76. package/dist/services/service.d.ts +0 -2
  77. package/dist/services/service.js +1 -2
  78. package/dist/services/toggle.d.ts +0 -2
  79. package/dist/services/toggle.js +1 -2
  80. package/dist/services/until.d.ts +0 -2
  81. package/dist/services/until.js +1 -2
  82. package/dist/shared-runtime.d.ts +0 -2
  83. package/dist/shared-runtime.js +1 -2
  84. package/dist/storage/createStorage.d.ts +0 -2
  85. package/dist/storage/createStorage.js +1 -2
  86. package/dist/storage/index.d.ts +0 -2
  87. package/dist/storage/index.js +1 -2
  88. package/dist/storage/providers.d.ts +0 -2
  89. package/dist/storage/providers.js +1 -2
  90. package/dist/storage/serializers.d.ts +0 -2
  91. package/dist/storage/serializers.js +1 -2
  92. package/dist/storage/sync.d.ts +0 -2
  93. package/dist/storage/sync.js +1 -2
  94. package/dist/storage/types.d.ts +0 -2
  95. package/dist/subpaths/BREAKPOINTS.js +1 -2
  96. package/dist/subpaths/Base.js +1 -2
  97. package/dist/subpaths/DIAGNOSTICS.js +1 -2
  98. package/dist/subpaths/DRAG_MODES.js +1 -2
  99. package/dist/subpaths/EVENTS.js +1 -2
  100. package/dist/subpaths/MOUNT_ATTRIBUTE.js +1 -2
  101. package/dist/subpaths/SWAP_MODES.js +1 -2
  102. package/dist/subpaths/children.js +1 -2
  103. package/dist/subpaths/component.js +1 -2
  104. package/dist/subpaths/createContext.js +1 -2
  105. package/dist/subpaths/createFallbackProvider.js +1 -2
  106. package/dist/subpaths/createGroup.js +1 -2
  107. package/dist/subpaths/createLocalStorage.js +1 -2
  108. package/dist/subpaths/createMemoryStorageProvider.js +1 -2
  109. package/dist/subpaths/createService.js +1 -2
  110. package/dist/subpaths/createServiceMixin.js +1 -2
  111. package/dist/subpaths/createSessionStorage.js +1 -2
  112. package/dist/subpaths/createStorage.js +1 -2
  113. package/dist/subpaths/createUrlSearchParamsInHashProvider.js +1 -2
  114. package/dist/subpaths/createUrlSearchParamsInHashStorage.js +1 -2
  115. package/dist/subpaths/createUrlSearchParamsProvider.js +1 -2
  116. package/dist/subpaths/createUrlSearchParamsStorage.js +1 -2
  117. package/dist/subpaths/defaultScheduler.js +1 -2
  118. package/dist/subpaths/defineManifest.js +1 -2
  119. package/dist/subpaths/domUpdate.js +1 -2
  120. package/dist/subpaths/emitExtendable.js +1 -2
  121. package/dist/subpaths/fromMetaGlob.js +1 -2
  122. package/dist/subpaths/fromWebpackContext.js +1 -2
  123. package/dist/subpaths/getBreakpoints.js +1 -2
  124. package/dist/subpaths/getInstance.js +1 -2
  125. package/dist/subpaths/getInstances.js +1 -2
  126. package/dist/subpaths/getMountedInstances.js +1 -2
  127. package/dist/subpaths/getUnmountedInstances.js +1 -2
  128. package/dist/subpaths/inject.js +1 -2
  129. package/dist/subpaths/injectContext.js +1 -2
  130. package/dist/subpaths/injectContextSync.js +1 -2
  131. package/dist/subpaths/jsonSerializer.js +1 -2
  132. package/dist/subpaths/localStorageProvider.js +1 -2
  133. package/dist/subpaths/memoryStorageProvider.js +1 -2
  134. package/dist/subpaths/namespaceQualifier.js +1 -2
  135. package/dist/subpaths/nextFrame.js +1 -2
  136. package/dist/subpaths/on.js +1 -2
  137. package/dist/subpaths/perTarget.js +1 -2
  138. package/dist/subpaths/provide.js +1 -2
  139. package/dist/subpaths/provideContext.js +1 -2
  140. package/dist/subpaths/provideRootContext.js +1 -2
  141. package/dist/subpaths/read.js +1 -2
  142. package/dist/subpaths/registerComponent.js +1 -2
  143. package/dist/subpaths/registerComponents.js +1 -2
  144. package/dist/subpaths/registerManifest.js +1 -2
  145. package/dist/subpaths/reportDiagnostic.js +1 -2
  146. package/dist/subpaths/sessionStorageProvider.js +1 -2
  147. package/dist/subpaths/setBreakpoints.js +1 -2
  148. package/dist/subpaths/signal.js +1 -2
  149. package/dist/subpaths/subscribeContext.js +1 -2
  150. package/dist/subpaths/swap.js +1 -2
  151. package/dist/subpaths/toggle.js +1 -2
  152. package/dist/subpaths/until.js +1 -2
  153. package/dist/subpaths/urlSearchParamsInHashProvider.js +1 -2
  154. package/dist/subpaths/urlSearchParamsProvider.js +1 -2
  155. package/dist/subpaths/useBreakpoint.js +1 -2
  156. package/dist/subpaths/useDrag.js +1 -2
  157. package/dist/subpaths/useInView.js +1 -2
  158. package/dist/subpaths/useKey.js +1 -2
  159. package/dist/subpaths/useMediaQuery.js +1 -2
  160. package/dist/subpaths/useMutation.js +1 -2
  161. package/dist/subpaths/usePointer.js +1 -2
  162. package/dist/subpaths/usePrefersReducedMotion.js +1 -2
  163. package/dist/subpaths/useRaf.js +1 -2
  164. package/dist/subpaths/useResize.js +1 -2
  165. package/dist/subpaths/useScroll.js +1 -2
  166. package/dist/subpaths/useScrollProgress.js +1 -2
  167. package/dist/subpaths/useWindowScroll.js +1 -2
  168. package/dist/subpaths/useWindowSize.js +1 -2
  169. package/dist/subpaths/utils/DEFAULT_DAMP_FACTOR.js +1 -2
  170. package/dist/subpaths/utils/INERTIA_FRAME.js +1 -2
  171. package/dist/subpaths/utils/MAX_SPRING_RATIO.js +1 -2
  172. package/dist/subpaths/utils/SCROLL_ALIGNMENTS.js +1 -2
  173. package/dist/subpaths/utils/SCROLL_AXES.js +1 -2
  174. package/dist/subpaths/utils/TRANSFORM_PROPS.js +1 -2
  175. package/dist/subpaths/utils/TRANSITION_OPTIONS.js +1 -2
  176. package/dist/subpaths/utils/camelCase.js +1 -2
  177. package/dist/subpaths/utils/capitalize.js +1 -2
  178. package/dist/subpaths/utils/clamp.js +1 -2
  179. package/dist/subpaths/utils/clamp01.js +1 -2
  180. package/dist/subpaths/utils/clampDampFactor.js +1 -2
  181. package/dist/subpaths/utils/createEaseInOut.js +1 -2
  182. package/dist/subpaths/utils/createEaseOut.js +1 -2
  183. package/dist/subpaths/utils/createElement.js +1 -2
  184. package/dist/subpaths/utils/createRange.js +1 -2
  185. package/dist/subpaths/utils/damp.js +1 -2
  186. package/dist/subpaths/utils/debounce.js +1 -2
  187. package/dist/subpaths/utils/decayOver.js +1 -2
  188. package/dist/subpaths/utils/deepmerge.js +1 -2
  189. package/dist/subpaths/utils/easeInCirc.js +1 -2
  190. package/dist/subpaths/utils/easeInCubic.js +1 -2
  191. package/dist/subpaths/utils/easeInExpo.js +1 -2
  192. package/dist/subpaths/utils/easeInOutCirc.js +1 -2
  193. package/dist/subpaths/utils/easeInOutCubic.js +1 -2
  194. package/dist/subpaths/utils/easeInOutExpo.js +1 -2
  195. package/dist/subpaths/utils/easeInOutQuad.js +1 -2
  196. package/dist/subpaths/utils/easeInOutQuart.js +1 -2
  197. package/dist/subpaths/utils/easeInOutQuint.js +1 -2
  198. package/dist/subpaths/utils/easeInOutSine.js +1 -2
  199. package/dist/subpaths/utils/easeInQuad.js +1 -2
  200. package/dist/subpaths/utils/easeInQuart.js +1 -2
  201. package/dist/subpaths/utils/easeInQuint.js +1 -2
  202. package/dist/subpaths/utils/easeInSine.js +1 -2
  203. package/dist/subpaths/utils/easeLinear.js +1 -2
  204. package/dist/subpaths/utils/easeOutCirc.js +1 -2
  205. package/dist/subpaths/utils/easeOutCubic.js +1 -2
  206. package/dist/subpaths/utils/easeOutExpo.js +1 -2
  207. package/dist/subpaths/utils/easeOutQuad.js +1 -2
  208. package/dist/subpaths/utils/easeOutQuart.js +1 -2
  209. package/dist/subpaths/utils/easeOutQuint.js +1 -2
  210. package/dist/subpaths/utils/easeOutSine.js +1 -2
  211. package/dist/subpaths/utils/enterTransition.js +1 -2
  212. package/dist/subpaths/utils/fold.js +1 -2
  213. package/dist/subpaths/utils/getOffsetSizes.js +1 -2
  214. package/dist/subpaths/utils/historyPush.js +1 -2
  215. package/dist/subpaths/utils/historyReplace.js +1 -2
  216. package/dist/subpaths/utils/inertiaDecay.js +1 -2
  217. package/dist/subpaths/utils/inertiaFinalValue.js +1 -2
  218. package/dist/subpaths/utils/inertiaStep.js +1 -2
  219. package/dist/subpaths/utils/inertiaTimeConstant.js +1 -2
  220. package/dist/subpaths/utils/isBoolean.js +1 -2
  221. package/dist/subpaths/utils/isDefined.js +1 -2
  222. package/dist/subpaths/utils/isFunction.js +1 -2
  223. package/dist/subpaths/utils/isNull.js +1 -2
  224. package/dist/subpaths/utils/isNumber.js +1 -2
  225. package/dist/subpaths/utils/isObject.js +1 -2
  226. package/dist/subpaths/utils/isString.js +1 -2
  227. package/dist/subpaths/utils/kebabCase.js +1 -2
  228. package/dist/subpaths/utils/leaveTransition.js +1 -2
  229. package/dist/subpaths/utils/lerp.js +1 -2
  230. package/dist/subpaths/utils/loadImage.js +1 -2
  231. package/dist/subpaths/utils/loadLink.js +1 -2
  232. package/dist/subpaths/utils/loadScript.js +1 -2
  233. package/dist/subpaths/utils/lockScroll.js +1 -2
  234. package/dist/subpaths/utils/lowerCase.js +1 -2
  235. package/dist/subpaths/utils/map.js +1 -2
  236. package/dist/subpaths/utils/matrix.js +1 -2
  237. package/dist/subpaths/utils/mean.js +1 -2
  238. package/dist/subpaths/utils/memo.js +1 -2
  239. package/dist/subpaths/utils/noop.js +1 -2
  240. package/dist/subpaths/utils/noopValue.js +1 -2
  241. package/dist/subpaths/utils/objectToURLSearchParams.js +1 -2
  242. package/dist/subpaths/utils/pascalCase.js +1 -2
  243. package/dist/subpaths/utils/random.js +1 -2
  244. package/dist/subpaths/utils/randomInt.js +1 -2
  245. package/dist/subpaths/utils/randomItem.js +1 -2
  246. package/dist/subpaths/utils/round.js +1 -2
  247. package/dist/subpaths/utils/saveActiveElement.js +1 -2
  248. package/dist/subpaths/utils/scrollPosition.js +1 -2
  249. package/dist/subpaths/utils/scrollTo.js +1 -2
  250. package/dist/subpaths/utils/selectorFor.js +1 -2
  251. package/dist/subpaths/utils/setClassesOrStyles.js +1 -2
  252. package/dist/subpaths/utils/smoothTo.js +1 -2
  253. package/dist/subpaths/utils/snakeCase.js +1 -2
  254. package/dist/subpaths/utils/spring.js +1 -2
  255. package/dist/subpaths/utils/throttle.js +1 -2
  256. package/dist/subpaths/utils/transform.js +1 -2
  257. package/dist/subpaths/utils/transition.js +1 -2
  258. package/dist/subpaths/utils/trapFocus.js +1 -2
  259. package/dist/subpaths/utils/untrapFocus.js +1 -2
  260. package/dist/subpaths/utils/upperCase.js +1 -2
  261. package/dist/subpaths/utils/wait.js +1 -2
  262. package/dist/subpaths/utils/withLeadingCharacters.js +1 -2
  263. package/dist/subpaths/utils/withLeadingSlash.js +1 -2
  264. package/dist/subpaths/utils/withTrailingCharacters.js +1 -2
  265. package/dist/subpaths/utils/withTrailingSlash.js +1 -2
  266. package/dist/subpaths/utils/withoutLeadingCharacters.js +1 -2
  267. package/dist/subpaths/utils/withoutLeadingCharactersRecursive.js +1 -2
  268. package/dist/subpaths/utils/withoutLeadingSlash.js +1 -2
  269. package/dist/subpaths/utils/withoutTrailingCharacters.js +1 -2
  270. package/dist/subpaths/utils/withoutTrailingCharactersRecursive.js +1 -2
  271. package/dist/subpaths/utils/withoutTrailingSlash.js +1 -2
  272. package/dist/subpaths/utils/wrap.js +1 -2
  273. package/dist/subpaths/viewTransition.js +1 -2
  274. package/dist/subpaths/warn.js +1 -2
  275. package/dist/subpaths/watchAttributeNamespace.js +1 -2
  276. package/dist/subpaths/watchAttributes.js +1 -2
  277. package/dist/subpaths/whenDOMSettled.js +1 -2
  278. package/dist/subpaths/withDrag.js +1 -2
  279. package/dist/subpaths/withInView.js +1 -2
  280. package/dist/subpaths/withKey.js +1 -2
  281. package/dist/subpaths/withMutation.js +1 -2
  282. package/dist/subpaths/withPointer.js +1 -2
  283. package/dist/subpaths/withRaf.js +1 -2
  284. package/dist/subpaths/withResize.js +1 -2
  285. package/dist/subpaths/withScroll.js +1 -2
  286. package/dist/subpaths/withScrollProgress.js +1 -2
  287. package/dist/subpaths/write.js +1 -2
  288. package/dist/swap.d.ts +0 -2
  289. package/dist/swap.js +1 -2
  290. package/dist/test/index.d.ts +0 -2
  291. package/dist/test/index.js +1 -2
  292. package/dist/utils/deepmerge.d.ts +0 -2
  293. package/dist/utils/deepmerge.js +1 -2
  294. package/dist/utils/dom.d.ts +0 -2
  295. package/dist/utils/dom.js +1 -2
  296. package/dist/utils/easings.d.ts +0 -2
  297. package/dist/utils/easings.js +1 -2
  298. package/dist/utils/focus.d.ts +0 -2
  299. package/dist/utils/focus.js +1 -2
  300. package/dist/utils/history.d.ts +0 -2
  301. package/dist/utils/history.js +1 -2
  302. package/dist/utils/is.d.ts +0 -2
  303. package/dist/utils/is.js +1 -2
  304. package/dist/utils/load.d.ts +0 -2
  305. package/dist/utils/load.js +1 -2
  306. package/dist/utils/maths.d.ts +0 -2
  307. package/dist/utils/maths.js +1 -2
  308. package/dist/utils/memo.d.ts +0 -2
  309. package/dist/utils/memo.js +1 -2
  310. package/dist/utils/noop.d.ts +0 -2
  311. package/dist/utils/noop.js +1 -2
  312. package/dist/utils/random.d.ts +0 -2
  313. package/dist/utils/random.js +1 -2
  314. package/dist/utils/scroll-lock.d.ts +0 -2
  315. package/dist/utils/scroll-lock.js +1 -2
  316. package/dist/utils/scrollTo.d.ts +0 -2
  317. package/dist/utils/scrollTo.js +1 -2
  318. package/dist/utils/selectors.d.ts +0 -2
  319. package/dist/utils/selectors.js +1 -2
  320. package/dist/utils/smoothTo.d.ts +0 -2
  321. package/dist/utils/smoothTo.js +1 -2
  322. package/dist/utils/strings.d.ts +0 -2
  323. package/dist/utils/strings.js +1 -2
  324. package/dist/utils/timing.d.ts +0 -2
  325. package/dist/utils/timing.js +1 -2
  326. package/dist/utils/transform.d.ts +0 -2
  327. package/dist/utils/transform.js +1 -2
  328. package/dist/utils/transition.d.ts +0 -2
  329. package/dist/utils/transition.js +1 -2
  330. package/dist/viewTransition.d.ts +0 -2
  331. package/dist/viewTransition.js +1 -2
  332. package/package.json +6 -3
  333. package/skills/studiometa-js-toolkit/SKILL.md +87 -0
  334. package/skills/studiometa-js-toolkit/references/api/configuration.md +169 -0
  335. package/skills/studiometa-js-toolkit/references/api/context/createContext.md +46 -0
  336. package/skills/studiometa-js-toolkit/references/api/context/createGroup.md +67 -0
  337. package/skills/studiometa-js-toolkit/references/api/context/index.md +69 -0
  338. package/skills/studiometa-js-toolkit/references/api/context/injectContext.md +58 -0
  339. package/skills/studiometa-js-toolkit/references/api/context/injectContextSync.md +44 -0
  340. package/skills/studiometa-js-toolkit/references/api/context/provideContext.md +61 -0
  341. package/skills/studiometa-js-toolkit/references/api/context/provideRootContext.md +42 -0
  342. package/skills/studiometa-js-toolkit/references/api/context/signal.md +85 -0
  343. package/skills/studiometa-js-toolkit/references/api/context/subscribeContext.md +71 -0
  344. package/skills/studiometa-js-toolkit/references/api/decorators/children.md +92 -0
  345. package/skills/studiometa-js-toolkit/references/api/decorators/component.md +75 -0
  346. package/skills/studiometa-js-toolkit/references/api/decorators/index.md +41 -0
  347. package/skills/studiometa-js-toolkit/references/api/decorators/inject.md +73 -0
  348. package/skills/studiometa-js-toolkit/references/api/decorators/on.md +149 -0
  349. package/skills/studiometa-js-toolkit/references/api/decorators/provide.md +77 -0
  350. package/skills/studiometa-js-toolkit/references/api/decorators/read-write.md +93 -0
  351. package/skills/studiometa-js-toolkit/references/api/diagnostics/DIAGNOSTICS.md +137 -0
  352. package/skills/studiometa-js-toolkit/references/api/diagnostics/EVENTS.md +45 -0
  353. package/skills/studiometa-js-toolkit/references/api/diagnostics/index.md +58 -0
  354. package/skills/studiometa-js-toolkit/references/api/diagnostics/reportDiagnostic.md +67 -0
  355. package/skills/studiometa-js-toolkit/references/api/diagnostics/warn.md +54 -0
  356. package/skills/studiometa-js-toolkit/references/api/dom/breakpoints.md +81 -0
  357. package/skills/studiometa-js-toolkit/references/api/dom/domUpdate.md +70 -0
  358. package/skills/studiometa-js-toolkit/references/api/dom/emitExtendable.md +68 -0
  359. package/skills/studiometa-js-toolkit/references/api/dom/index.md +26 -0
  360. package/skills/studiometa-js-toolkit/references/api/dom/swap.md +105 -0
  361. package/skills/studiometa-js-toolkit/references/api/dom/watchAttributeNamespace.md +96 -0
  362. package/skills/studiometa-js-toolkit/references/api/dom/watchAttributes.md +56 -0
  363. package/skills/studiometa-js-toolkit/references/api/dom/whenDOMSettled.md +41 -0
  364. package/skills/studiometa-js-toolkit/references/api/html/data-component.md +105 -0
  365. package/skills/studiometa-js-toolkit/references/api/html/data-mount.md +69 -0
  366. package/skills/studiometa-js-toolkit/references/api/html/data-option.md +106 -0
  367. package/skills/studiometa-js-toolkit/references/api/html/data-ref.md +63 -0
  368. package/skills/studiometa-js-toolkit/references/api/html/index.md +32 -0
  369. package/skills/studiometa-js-toolkit/references/api/index.md +73 -0
  370. package/skills/studiometa-js-toolkit/references/api/instance-events.md +75 -0
  371. package/skills/studiometa-js-toolkit/references/api/instance-methods.md +267 -0
  372. package/skills/studiometa-js-toolkit/references/api/instance-properties.md +90 -0
  373. package/skills/studiometa-js-toolkit/references/api/methods-hooks-events.md +149 -0
  374. package/skills/studiometa-js-toolkit/references/api/methods-hooks-lifecycle.md +90 -0
  375. package/skills/studiometa-js-toolkit/references/api/methods-hooks-options.md +96 -0
  376. package/skills/studiometa-js-toolkit/references/api/methods-hooks-services.md +164 -0
  377. package/skills/studiometa-js-toolkit/references/api/registry/defineManifest.md +57 -0
  378. package/skills/studiometa-js-toolkit/references/api/registry/fromMetaGlob.md +33 -0
  379. package/skills/studiometa-js-toolkit/references/api/registry/fromWebpackContext.md +37 -0
  380. package/skills/studiometa-js-toolkit/references/api/registry/getInstance.md +52 -0
  381. package/skills/studiometa-js-toolkit/references/api/registry/getInstances.md +48 -0
  382. package/skills/studiometa-js-toolkit/references/api/registry/getMountedInstances.md +39 -0
  383. package/skills/studiometa-js-toolkit/references/api/registry/getUnmountedInstances.md +46 -0
  384. package/skills/studiometa-js-toolkit/references/api/registry/index.md +49 -0
  385. package/skills/studiometa-js-toolkit/references/api/registry/registerComponent.md +93 -0
  386. package/skills/studiometa-js-toolkit/references/api/registry/registerComponents.md +37 -0
  387. package/skills/studiometa-js-toolkit/references/api/registry/registerManifest.md +72 -0
  388. package/skills/studiometa-js-toolkit/references/api/scheduler/defaultScheduler.md +104 -0
  389. package/skills/studiometa-js-toolkit/references/api/scheduler/index.md +27 -0
  390. package/skills/studiometa-js-toolkit/references/api/scheduler/nextFrame.md +31 -0
  391. package/skills/studiometa-js-toolkit/references/api/scheduler/viewTransition.md +53 -0
  392. package/skills/studiometa-js-toolkit/references/api/services/createService.md +95 -0
  393. package/skills/studiometa-js-toolkit/references/api/services/createServiceMixin.md +81 -0
  394. package/skills/studiometa-js-toolkit/references/api/services/index.md +94 -0
  395. package/skills/studiometa-js-toolkit/references/api/services/mixins.md +148 -0
  396. package/skills/studiometa-js-toolkit/references/api/services/perTarget.md +65 -0
  397. package/skills/studiometa-js-toolkit/references/api/services/toggle.md +80 -0
  398. package/skills/studiometa-js-toolkit/references/api/services/until.md +44 -0
  399. package/skills/studiometa-js-toolkit/references/api/services/useBreakpoint.md +42 -0
  400. package/skills/studiometa-js-toolkit/references/api/services/useDrag.md +119 -0
  401. package/skills/studiometa-js-toolkit/references/api/services/useInView.md +64 -0
  402. package/skills/studiometa-js-toolkit/references/api/services/useKey.md +105 -0
  403. package/skills/studiometa-js-toolkit/references/api/services/useMediaQuery.md +45 -0
  404. package/skills/studiometa-js-toolkit/references/api/services/useMutation.md +69 -0
  405. package/skills/studiometa-js-toolkit/references/api/services/usePointer.md +91 -0
  406. package/skills/studiometa-js-toolkit/references/api/services/usePrefersReducedMotion.md +42 -0
  407. package/skills/studiometa-js-toolkit/references/api/services/useRaf.md +91 -0
  408. package/skills/studiometa-js-toolkit/references/api/services/useResize.md +60 -0
  409. package/skills/studiometa-js-toolkit/references/api/services/useScroll.md +88 -0
  410. package/skills/studiometa-js-toolkit/references/api/services/useScrollProgress.md +88 -0
  411. package/skills/studiometa-js-toolkit/references/api/services/useWindowScroll.md +25 -0
  412. package/skills/studiometa-js-toolkit/references/api/services/useWindowSize.md +25 -0
  413. package/skills/studiometa-js-toolkit/references/api/storage/createStorage.md +126 -0
  414. package/skills/studiometa-js-toolkit/references/api/storage/index.md +33 -0
  415. package/skills/studiometa-js-toolkit/references/api/storage/presets.md +58 -0
  416. package/skills/studiometa-js-toolkit/references/api/storage/providers.md +109 -0
  417. package/skills/studiometa-js-toolkit/references/api/test/index.md +214 -0
  418. package/skills/studiometa-js-toolkit/references/guide/concepts/attribute-grammar.md +93 -0
  419. package/skills/studiometa-js-toolkit/references/guide/concepts/mutation-engine.md +71 -0
  420. package/skills/studiometa-js-toolkit/references/guide/concepts/philosophy.md +78 -0
  421. package/skills/studiometa-js-toolkit/references/guide/concepts/the-registry.md +110 -0
  422. package/skills/studiometa-js-toolkit/references/guide/going-further/autoloading.md +104 -0
  423. package/skills/studiometa-js-toolkit/references/guide/going-further/handling-diagnostics.md +104 -0
  424. package/skills/studiometa-js-toolkit/references/guide/going-further/mount-strategies.md +95 -0
  425. package/skills/studiometa-js-toolkit/references/guide/going-further/scheduling-work.md +124 -0
  426. package/skills/studiometa-js-toolkit/references/guide/going-further/sharing-state.md +218 -0
  427. package/skills/studiometa-js-toolkit/references/guide/going-further/swapping-content.md +92 -0
  428. package/skills/studiometa-js-toolkit/references/guide/going-further/testing-components.md +137 -0
  429. package/skills/studiometa-js-toolkit/references/guide/going-further/typing-components.md +190 -0
  430. package/skills/studiometa-js-toolkit/references/guide/going-further/using-decorators.md +168 -0
  431. package/skills/studiometa-js-toolkit/references/guide/going-further/using-storage.md +125 -0
  432. package/skills/studiometa-js-toolkit/references/guide/index.md +163 -0
  433. package/skills/studiometa-js-toolkit/references/guide/introduction/installation.md +144 -0
  434. package/skills/studiometa-js-toolkit/references/guide/introduction/lifecycle-hooks.md +174 -0
  435. package/skills/studiometa-js-toolkit/references/guide/introduction/managing-components.md +229 -0
  436. package/skills/studiometa-js-toolkit/references/guide/introduction/managing-options.md +235 -0
  437. package/skills/studiometa-js-toolkit/references/guide/introduction/managing-refs.md +174 -0
  438. package/skills/studiometa-js-toolkit/references/guide/introduction/using-services.md +218 -0
  439. package/skills/studiometa-js-toolkit/references/guide/introduction/working-with-events.md +251 -0
  440. package/skills/studiometa-js-toolkit/references/guide/migration/v3-to-v4.md +373 -0
  441. package/skills/studiometa-js-toolkit/references/utils/css.md +98 -0
  442. package/skills/studiometa-js-toolkit/references/utils/dom.md +54 -0
  443. package/skills/studiometa-js-toolkit/references/utils/easings.md +217 -0
  444. package/skills/studiometa-js-toolkit/references/utils/focus.md +84 -0
  445. package/skills/studiometa-js-toolkit/references/utils/history.md +69 -0
  446. package/skills/studiometa-js-toolkit/references/utils/index.md +53 -0
  447. package/skills/studiometa-js-toolkit/references/utils/is.md +84 -0
  448. package/skills/studiometa-js-toolkit/references/utils/load.md +59 -0
  449. package/skills/studiometa-js-toolkit/references/utils/math.md +129 -0
  450. package/skills/studiometa-js-toolkit/references/utils/motion.md +218 -0
  451. package/skills/studiometa-js-toolkit/references/utils/objects.md +68 -0
  452. package/skills/studiometa-js-toolkit/references/utils/scroll.md +128 -0
  453. package/skills/studiometa-js-toolkit/references/utils/strings.md +176 -0
  454. package/skills/studiometa-js-toolkit/references/utils/timing.md +111 -0
  455. package/skills/studiometa-js-toolkit/references/utils/transitions.md +122 -0
@@ -0,0 +1,25 @@
1
+ # useWindowScroll
2
+
3
+ ```ts
4
+ useWindowScroll(): Service<ScrollProps>
5
+ ```
6
+
7
+ The page scroll. It names the default case of [`useScroll()`](useScroll.md), and it is the same instance as `useScroll()` and `useScroll(document.documentElement)`.
8
+
9
+ ## Usage
10
+
11
+ ```js
12
+ import { useWindowScroll } from '@studiometa/js-toolkit';
13
+
14
+ const unsubscribe = useWindowScroll().subscribe(({ y, progressY }) => {
15
+ document.documentElement.style.setProperty('--scroll-progress', String(progressY));
16
+ });
17
+ ```
18
+
19
+ Props, coalescing and extent observation are [`useScroll()`](useScroll.md)'s.
20
+
21
+ ## Why it exists
22
+
23
+ `useScroll()` already defaults to the document element, so this export adds no behaviour. It adds a **name**: a call site that means "the page" says so, instead of relying on a reader knowing what the default argument is.
24
+
25
+ `useWindowSize()` is the same idea for [`useResize()`](useResize.md).
@@ -0,0 +1,25 @@
1
+ # useWindowSize
2
+
3
+ ```ts
4
+ useWindowSize(): Service<ResizeProps>
5
+ ```
6
+
7
+ The viewport size. It names the default case of [`useResize()`](useResize.md).
8
+
9
+ ## Usage
10
+
11
+ ```js
12
+ import { useWindowSize } from '@studiometa/js-toolkit';
13
+
14
+ const unsubscribe = useWindowSize().subscribe(({ width, height, orientation }) => {
15
+ console.log(width, height, orientation);
16
+ });
17
+ ```
18
+
19
+ Props are [`useResize()`](useResize.md)'s.
20
+
21
+ ## The viewport is not an observed box
22
+
23
+ A `ResizeObserver` reports the box of the element it observes. For the root element, `clientWidth` and `clientHeight` report the **viewport** and are decoupled from that box, so this service keeps a `resize` listener beside the observer.
24
+
25
+ That is the difference between asking for the window and asking for an element that happens to be full-width.
@@ -0,0 +1,126 @@
1
+ # createStorage
2
+
3
+ ```ts
4
+ createStorage<T extends object = Record<string, unknown>>(options?: StorageOptions): StorageInstance<T>
5
+ ```
6
+
7
+ A typed, observable key-value store.
8
+
9
+ ```ts
10
+ interface StorageOptions {
11
+ provider?: StorageProvider;
12
+ serializer?: StorageSerializer;
13
+ prefix?: string;
14
+ }
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ```ts
20
+ import { createStorage, memoryStorageProvider } from '@studiometa/js-toolkit';
21
+
22
+ interface Prefs {
23
+ theme: 'light' | 'dark';
24
+ seen: string[];
25
+ }
26
+
27
+ const prefs = createStorage<Prefs>({
28
+ provider: memoryStorageProvider,
29
+ prefix: 'app:',
30
+ });
31
+
32
+ prefs.set('theme', 'dark');
33
+ prefs.get('theme'); // 'light' | 'dark' | undefined
34
+ prefs.get('theme', 'light'); // 'light' | 'dark'
35
+ prefs.has('seen');
36
+ prefs.keys();
37
+ prefs.delete('seen');
38
+ prefs.clear();
39
+ prefs.destroy();
40
+ ```
41
+
42
+ ## The instance
43
+
44
+ ```ts
45
+ interface StorageInstance<T extends object = Record<string, unknown>> {
46
+ get<K extends keyof T>(key: K): T[K] | undefined;
47
+ get<K extends keyof T>(key: K, defaultValue: T[K]): T[K];
48
+ set<K extends keyof T>(key: K, value: T[K]): void;
49
+ delete<K extends keyof T>(key: K): void;
50
+ has<K extends keyof T>(key: K): boolean;
51
+ keys(): (keyof T)[];
52
+ clear(): void;
53
+ subscribe<K extends keyof T>(
54
+ key: K,
55
+ callback: (value: T[K] | undefined) => void,
56
+ options?: { immediate?: boolean },
57
+ ): () => void;
58
+ destroy(): void;
59
+ }
60
+ ```
61
+
62
+ The two `get` overloads are the whole difference between "it may not be there" and "here is what to use if it is not".
63
+
64
+ ## Observing a key
65
+
66
+ ```ts
67
+ import { createStorage } from '@studiometa/js-toolkit';
68
+
69
+ interface Prefs {
70
+ theme: 'light' | 'dark';
71
+ }
72
+ const prefs = createStorage<Prefs>();
73
+ const unsubscribe = prefs.subscribe(
74
+ 'theme',
75
+ (value) => {
76
+ document.documentElement.dataset.theme = value ?? 'light';
77
+ },
78
+ { immediate: true },
79
+ );
80
+ ```
81
+
82
+ A [`Signal`](../context/signal.md) is created **per key, on the first subscription**, so a store nobody observes holds nothing.
83
+
84
+ In a component, hand the unsubscribe back from `mounted()`:
85
+
86
+ ```js
87
+ mounted() {
88
+ return prefs.subscribe('theme', (value) => this.apply(value));
89
+ }
90
+ ```
91
+
92
+ ## `destroy()`
93
+
94
+ Releases every subscription and the shared sync listeners at once. A store that outlives the page needs no call; a store scoped to a component does.
95
+
96
+ ## `prefix`
97
+
98
+ Namespaces every key in the underlying provider, so two stores can share one backing area without colliding. The prefix is the store's business — a provider never sees an unprefixed key and never adds one.
99
+
100
+ ## `serializer`
101
+
102
+ ```ts
103
+ interface StorageSerializer {
104
+ serialize(value: unknown): string;
105
+ deserialize(value: string): unknown;
106
+ }
107
+ ```
108
+
109
+ Defaults to `jsonSerializer`. Failures are reported, not thrown:
110
+
111
+ - `storage.serialize-failed` — **nothing is written**;
112
+ - `storage.deserialize-failed` — the default is returned.
113
+
114
+ ## Syncing with the outside
115
+
116
+ `syncEvents` on the provider is a list of window event names and nothing more. `createStorage()` subscribes **one shared, reference-counted listener per name** while at least one key is observed, and re-reads every observed key when it fires.
117
+
118
+ The event carries no usable state, so the subscriber re-reads rather than trusting a payload.
119
+
120
+ **A known gap**
121
+
122
+ A provider whose changes arrive on a `BroadcastChannel` or through an observer has no way to announce them yet.
123
+
124
+ ## In Node
125
+
126
+ One storage instance runs in Node over the memory provider, which is what `test/package-node-consumer.js` exercises. Nothing in the store touches `window` unless a provider's `syncEvents` asks for it.
@@ -0,0 +1,33 @@
1
+ # Storage
2
+
3
+ **One seam, six adapters.** `createStorage()` is a typed, observable key-value store over a `StorageProvider`.
4
+
5
+ ## The exports
6
+
7
+ - [`createStorage(options?)`](createStorage.md) — the store
8
+ - [Presets](presets.md) — `createLocalStorage()`, `createSessionStorage()`, `createUrlSearchParamsStorage()`, `createUrlSearchParamsInHashStorage()`
9
+ - [Providers](providers.md) — the six adapters, and how to write one
10
+
11
+ ## The division of labour
12
+
13
+ **`createStorage()` owns everything a consumer thinks of as storage**: key namespacing through `prefix`, serialization in both directions, a `Signal` per key created on the first subscription, and the reference-counted wiring that keeps observed keys in sync.
14
+
15
+ **A provider moves strings only** — six synchronous methods, plus an optional list of window event names.
16
+
17
+ ```
18
+ consumer → StorageInstance<T> typed, observable, prefixed, serialized
19
+ ↓
20
+ StorageProvider get/set/remove/has/keys/clear + syncEvents
21
+ ↓
22
+ localStorage, a Map, location.search, …
23
+ ```
24
+
25
+ That is why a custom backend is six small methods, and why one storage instance runs in Node over the memory provider.
26
+
27
+ ## Failures are diagnostics, never throws
28
+
29
+ A built-in provider turns a full quota or a refused area into a `storage.access-failed` diagnostic and returns the method's fallback: `null`, `false`, `[]` or `undefined`. The store's own failures are `storage.serialize-failed` — after which nothing is written — and `storage.deserialize-failed` — after which the default is returned.
30
+
31
+ ## Read next
32
+
33
+ [Storage](../../guide/going-further/using-storage.md).
@@ -0,0 +1,58 @@
1
+ # Storage presets
2
+
3
+ Four presets that each remove an argument from every call site.
4
+
5
+ ```ts
6
+ createLocalStorage<T>(options?): StorageInstance<T>
7
+ createSessionStorage<T>(options?): StorageInstance<T>
8
+ createUrlSearchParamsStorage<T>(options?): StorageInstance<T>
9
+ createUrlSearchParamsInHashStorage<T>(options?): StorageInstance<T>
10
+ ```
11
+
12
+ Their options are [`createStorage()`](createStorage.md)'s **without `provider`** — the preset supplies it. The two URL presets also take `push`.
13
+
14
+ ## Usage
15
+
16
+ ```ts
17
+ import {
18
+ createLocalStorage,
19
+ createSessionStorage,
20
+ createUrlSearchParamsInHashStorage,
21
+ createUrlSearchParamsStorage,
22
+ } from '@studiometa/js-toolkit';
23
+
24
+ interface Prefs {
25
+ theme: 'light' | 'dark';
26
+ }
27
+
28
+ createLocalStorage<Prefs>({ prefix: 'app:' });
29
+ createSessionStorage<Prefs>();
30
+ createUrlSearchParamsStorage<Prefs>({ push: true });
31
+ createUrlSearchParamsInHashStorage<Prefs>();
32
+ ```
33
+
34
+ ## `push`
35
+
36
+ The two URL presets choose `history.pushState` over the default `replaceState`:
37
+
38
+ | `push` | Each write |
39
+ | ------- | -------------------------- |
40
+ | `false` | replaces the current entry |
41
+ | `true` | adds a history entry |
42
+
43
+ `true` is what makes a filter state navigable with the back button. `false` is what keeps a scroll position or a tab index out of the history.
44
+
45
+ ## Which URL preset
46
+
47
+ | Preset | Reads and writes | Survives |
48
+ | -------------------------------------- | -------------------------- | ---------------------------------------- |
49
+ | `createUrlSearchParamsStorage()` | `location.search` | a share, a bookmark, the server |
50
+ | `createUrlSearchParamsInHashStorage()` | `location.hash`, as params | a share and a bookmark, never the server |
51
+
52
+ Both rebuild the **whole location** on each write, so a search write keeps the hash and a hash write keeps the query string.
53
+
54
+ ## Why only these four
55
+
56
+ **A factory exists only where its product has state.** These four each replace an argument at every call site, which is worth an export. `createLocalStorageProvider()` and `createSessionStorageProvider()` are **removed** — the instances say the same thing with nothing to call.
57
+
58
+ See [Providers](providers.md).
@@ -0,0 +1,109 @@
1
+ # Storage providers
2
+
3
+ A provider moves **strings only**.
4
+
5
+ ```ts
6
+ interface StorageProvider {
7
+ get(key: string): string | null;
8
+ set(key: string, value: string): void;
9
+ remove(key: string): void;
10
+ has(key: string): boolean;
11
+ keys(): string[];
12
+ clear(): void;
13
+ syncEvents?: readonly string[];
14
+ }
15
+ ```
16
+
17
+ ## The six adapters
18
+
19
+ | Adapter | Backed by | `syncEvents` |
20
+ | --------------------------------------------------------------------------------- | ------------------------------------------------------ | ------------------------ |
21
+ | `localStorageProvider` | `localStorage` | `storage` |
22
+ | `sessionStorageProvider` | `sessionStorage` | `storage` |
23
+ | `memoryStorageProvider` / `createMemoryStorageProvider()` | a `Map` | — |
24
+ | `createFallbackProvider(...providers)` | reads from the first that holds the key, writes to all | the union |
25
+ | `urlSearchParamsProvider` / `createUrlSearchParamsProvider(options?)` | `location.search` | `popstate` |
26
+ | `urlSearchParamsInHashProvider` / `createUrlSearchParamsInHashProvider(options?)` | `location.hash`, as params | `popstate`, `hashchange` |
27
+
28
+ ```ts
29
+ import {
30
+ createFallbackProvider,
31
+ createMemoryStorageProvider,
32
+ createStorage,
33
+ localStorageProvider,
34
+ memoryStorageProvider,
35
+ } from '@studiometa/js-toolkit';
36
+
37
+ // Try localStorage, fall back to memory when it is refused.
38
+ createStorage({
39
+ provider: createFallbackProvider(localStorageProvider, memoryStorageProvider),
40
+ });
41
+
42
+ // A private Map, not the shared singleton.
43
+ createStorage({ provider: createMemoryStorageProvider() });
44
+ ```
45
+
46
+ **The memory singleton is shared**
47
+
48
+ `memoryStorageProvider` is one `Map` for the whole page. Two stores over it see each other's keys unless they use different prefixes. For a store per component, use `createMemoryStorageProvider()`.
49
+
50
+ ## `createFallbackProvider()`
51
+
52
+ Reads from the **first provider that holds the key** and writes to **all** of them. That is what makes "use localStorage where it works, memory where it does not" one line rather than a branch at every call site.
53
+
54
+ ## A factory exists only where its product has state
55
+
56
+ | Has state or arguments | Does not |
57
+ | ----------------------------------------------- | -------------------------- |
58
+ | `createMemoryStorageProvider()` — a `Map` | `localStorageProvider` |
59
+ | `createFallbackProvider(...)` | `sessionStorageProvider` |
60
+ | `createUrlSearchParamsProvider(options?)` | `memoryStorageProvider` |
61
+ | `createUrlSearchParamsInHashProvider(options?)` | the two bare URL instances |
62
+
63
+ `createLocalStorageProvider()` and `createSessionStorageProvider()` are removed; the instances stay.
64
+
65
+ ## A built-in provider never throws
66
+
67
+ `guard()` turns a full quota or a refused area into a `storage.access-failed` diagnostic and returns the method's fallback:
68
+
69
+ | Method | Fallback |
70
+ | ------------------------ | ----------- |
71
+ | `get` | `null` |
72
+ | `has` | `false` |
73
+ | `keys` | `[]` |
74
+ | `set`, `remove`, `clear` | `undefined` |
75
+
76
+ It reports **once per operation**, not once per area. **The area is resolved per call, inside the guard**, because the getter itself throws when storage is denied — `localStorage` in a blocked third-party frame throws on access, not on use.
77
+
78
+ `types.ts` states the same contract for a custom provider: report, return the fallback, do not throw.
79
+
80
+ ## The URL adapters
81
+
82
+ They **rebuild the whole location on each write**, so a search write keeps the hash and a hash write keeps the query string. Their one option is `push`, which chooses `history.pushState` over the default `replaceState`.
83
+
84
+ ## Writing your own
85
+
86
+ ```ts
87
+ import { createStorage, type StorageProvider } from '@studiometa/js-toolkit';
88
+
89
+ const cookieProvider: StorageProvider = {
90
+ get: (key) => new URLSearchParams(document.cookie.replaceAll('; ', '&')).get(key),
91
+ set: (key, value) => {
92
+ document.cookie = `${key}=${value};path=/`;
93
+ },
94
+ remove: (key) => {
95
+ document.cookie = `${key}=;path=/;max-age=0`;
96
+ },
97
+ has: (key) => document.cookie.includes(`${key}=`),
98
+ keys: () => [...new URLSearchParams(document.cookie.replaceAll('; ', '&')).keys()],
99
+ clear: () => {},
100
+ };
101
+
102
+ const store = createStorage({ provider: cookieProvider });
103
+ ```
104
+
105
+ Six synchronous string methods. Namespacing, serialization, signals and sync wiring are [`createStorage()`](createStorage.md)'s — do none of it here.
106
+
107
+ ## Tested at the seam
108
+
109
+ `providers.spec.ts` drives each adapter through the six methods for real, including a `setItem` that throws, an area getter that throws, `push` against `history.length`, and the `syncEvents` names of each adapter.
@@ -0,0 +1,214 @@
1
+ # Test helpers
2
+
3
+ ```js
4
+ import { mount, settle, waitFor } from '@studiometa/js-toolkit/test';
5
+ ```
6
+
7
+ Nine helpers a component test cannot write for itself.
8
+
9
+ ## Why the subpath exists
10
+
11
+ **The timing recipe is not derivable.** "Has this component mounted and finished its writes?" is answered by five rounds of a 10 ms timer followed by `defaultScheduler.whenIdle()`, and those two numbers encode the mount observer's delivery latency and the scheduler's lane order.
12
+
13
+ Neither half works alone: `whenIdle()` can resolve before the observer has reported the element, and a timer can return between two lanes. `defaultScheduler` and `nextFrame` were already public, so the pieces shipped and the recipe did not.
14
+
15
+ **It depends on no test framework.** Nothing in the module imports a runner, an assertion library or a spy; it reads the DOM and the scheduler only, so it runs under Vitest, under Playwright and on a plain browser page. That is also why it is not on the root barrel: a page has no use for it, and the root export count stays what it was.
16
+
17
+ ## `mount()`
18
+
19
+ ```ts
20
+ mount(html: string): Promise<HTMLElement>
21
+ ```
22
+
23
+ Inserts the markup and resolves once the eager components have mounted.
24
+
25
+ ```js
26
+ const root = await mount(`
27
+ <button data-component="Counter">
28
+ <span data-ref="output">0</span>
29
+ </button>
30
+ `);
31
+ ```
32
+
33
+ **It returns the wrapper `div` it created**, never the markup's own root, so a fragment of several siblings works and `querySelector()` has a stable handle. `.firstElementChild` is one property away.
34
+
35
+ ## `settle()`
36
+
37
+ ```ts
38
+ settle(): Promise<void>
39
+ ```
40
+
41
+ Resolves once the framework has caught up — the same recipe `mount()` uses.
42
+
43
+ **Not for a transition's end state**
44
+
45
+ `settle()` is generous rather than deterministic. See [Transitions](#transitions) below.
46
+
47
+ ## `frames()`
48
+
49
+ ```ts
50
+ frames(count?: number): Promise<void>
51
+ ```
52
+
53
+ Awaits animation frames. `nextFrame()` with a count.
54
+
55
+ ## `waitFor()`
56
+
57
+ ```ts
58
+ waitFor<T>(predicate: () => T | false | null | undefined, options?: { timeout?: number; message?: string }): Promise<T>
59
+ ```
60
+
61
+ Polls until the predicate is truthy and **returns that value**, which makes the same call either a guard or a query:
62
+
63
+ ```js
64
+ // a guard
65
+ await waitFor(() => el.classList.contains('is-open'));
66
+
67
+ // a query
68
+ const panel = await waitFor(() => root.querySelector('.panel'));
69
+ ```
70
+
71
+ It polls on a **10 ms cadence and drains the scheduler between attempts**. On timeout it throws — with the caller's `message`, or one naming the timeout.
72
+
73
+ ## `captureDiagnostics()`
74
+
75
+ ```ts
76
+ captureDiagnostics(target?: EventTarget): { codes: string[]; entries: ToolkitDiagnosticDetail[]; stop(): void }
77
+ ```
78
+
79
+ ```js
80
+ const diagnostics = captureDiagnostics();
81
+ // … exercise the component
82
+ expect(diagnostics.codes).toContain('ref.mismatch');
83
+ diagnostics.stop();
84
+ ```
85
+
86
+ **It reads the channel, and asserting on `console.warn` does not.** A recovered failure is reported on a cancelable event whose _default behaviour_ is the console line; a spy on that line cannot see the code, the severity or the reporting component, and it passes for the wrong diagnostic.
87
+
88
+ The helper **cancels each event as it arrives**, which is the same act that suppresses the sink — so collecting and silencing are one step, not two, and no spy is involved.
89
+
90
+ `target` defaults to `document`, which sees everything a connected element reported, because diagnostics bubble and compose.
91
+
92
+ ## `recordEvents()`
93
+
94
+ ```ts
95
+ recordEvents(target: EventTarget, ...types: string[]): { events: { type: string; detail: unknown }[]; stop(): void }
96
+ ```
97
+
98
+ ```js
99
+ const recording = recordEvents(el, 'open', 'opened');
100
+
101
+ el.querySelector('button').click();
102
+
103
+ await waitFor(() => recording.events.length === 2);
104
+ expect(recording.events.map(({ type }) => type)).toEqual(['open', 'opened']);
105
+ expect(recording.events[1].detail).toEqual({ height: 120 });
106
+
107
+ recording.stop();
108
+ ```
109
+
110
+ **It keeps the order and the payloads.** A component's contract is "`open` came before `opened`, and `opened` carried the height it measured", and a call-counting spy throws both away.
111
+
112
+ Recording several types into one array is the only place their **relative order** is visible. The richer `{ type, detail }` shape ships because a caller wanting names alone can map, and the reverse is impossible.
113
+
114
+ `$emit` dispatches synchronously but is almost never _called_ synchronously, so the count is awaited with `waitFor`, not read.
115
+
116
+ ## `countRequestedFrames()`
117
+
118
+ ```ts
119
+ countRequestedFrames(during: () => Promise<void> | void): Promise<number>
120
+ ```
121
+
122
+ ```js
123
+ const frames = await countRequestedFrames(async () => {
124
+ for (let i = 0; i < 10; i += 1) el.dispatchEvent(new Event('scroll'));
125
+ await settle();
126
+ });
127
+ expect(frames).toBeLessThan(3);
128
+ ```
129
+
130
+ **It patches a global, and says so.** It swaps `globalThis.requestAnimationFrame` for a counting wrapper that forwards to the original, and restores it in a `finally` — so it comes back whether `during` returns or throws.
131
+
132
+ It is here despite the patch because the assertion it serves, "this did not schedule a frame per event", has no other seam: the framework's own scheduler makes the calls, so there is nothing of the component's for a spy to sit on.
133
+
134
+ **Two concurrent calls would nest their wrappers. Do not.**
135
+
136
+ ## `resetDom()`
137
+
138
+ ```ts
139
+ resetDom(): Promise<void>
140
+ ```
141
+
142
+ Empties the document body and lets the teardown run.
143
+
144
+ ## `resetRegistry()`
145
+
146
+ ```ts
147
+ resetRegistry(): void
148
+ ```
149
+
150
+ **The inverse `registerComponent()` deliberately lacks.** A page registers once and keeps it; a test suite is the one caller for which a page-wide registry surviving `resetDom()` is wrong, and the workaround it forces is a counter minting `Widget-1`, `Widget-2`.
151
+
152
+ It is **coarse on purpose**: the element→controller map is a `WeakMap`, so it cannot be enumerated, nothing can walk it to dispose live triggers, and a `querySelectorAll()` sweep would still miss detached elements. Clearing everything works because the mutation-observer path already disposes a controller as its element leaves the DOM — **hence the call belongs after `resetDom()`**.
153
+
154
+ Two things it does not do: it cannot clear that `WeakMap`, so empty the DOM first; and it does not narrow the attribute filter the shared observer built from everything ever registered — an extra watched attribute costs a reconciliation pass that finds no owner, and nothing more.
155
+
156
+ **Never in an `afterEach`**
157
+
158
+ Spec files register at module top level, so this in an `afterEach` silently unregisters everything for every later test in the file. Put it in an `afterAll`, or call it and register again straight away:
159
+
160
+ ```js
161
+ afterEach(async () => {
162
+ await resetDom();
163
+ resetRegistry();
164
+ registerComponents(Subject, Emitter);
165
+ });
166
+ ```
167
+
168
+ ## Transitions {#transitions}
169
+
170
+ **A transition's end state is asserted by polling, never by `settle()`.** A method that starts a transition does not hand it back, and a kept end state lands only after `nextFrame()`, the `from` and `active` states, and either a `transitionend` or one more frame. `settle()` is generous rather than deterministic, which is a flake that passes alone and fails under load.
171
+
172
+ **Polling for an _absence_ is wrong** for the mirror-image reason: `leaveTransition()` clears the other direction's `to` state synchronously, so the poll passes before anything has happened.
173
+
174
+ ## What is deliberately not in it
175
+
176
+ An instance lookup — [`getInstance()`](../registry/getInstance.md) and [`getInstances()`](../registry/getInstances.md) on the root barrel answer it — fetch stubs, and pointer sequences. Each is either specific to one spec or already served by `vi.fn()` and `@vitest/browser`'s `userEvent`.
177
+
178
+ ## A full example
179
+
180
+ ```js
181
+ import { afterAll, expect, test } from 'vitest';
182
+ import { Base, registerComponent } from '@studiometa/js-toolkit';
183
+ import { mount, resetDom, resetRegistry, waitFor } from '@studiometa/js-toolkit/test';
184
+
185
+ class Counter extends Base {
186
+ static config = { name: 'Counter', refs: ['output'] };
187
+
188
+ count = 0;
189
+
190
+ onClick() {
191
+ this.count += 1;
192
+ this.$refs.output.textContent = String(this.count);
193
+ }
194
+ }
195
+
196
+ registerComponent(Counter);
197
+
198
+ test('it counts clicks', async () => {
199
+ const root = await mount(`
200
+ <button data-component="Counter">
201
+ <span data-ref="output">0</span>
202
+ </button>
203
+ `);
204
+
205
+ root.querySelector('button').click();
206
+
207
+ await waitFor(() => root.querySelector('[data-ref="output"]').textContent === '1');
208
+ });
209
+
210
+ afterAll(async () => {
211
+ await resetDom();
212
+ resetRegistry();
213
+ });
214
+ ```