@mhmo91/schmancy 0.10.12 → 0.10.14
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.
- package/README.md +11 -11
- package/dist/agent/schmancy.agent.js +1 -1
- package/dist/agent/schmancy.agent.js.map +1 -1
- package/dist/agent/schmancy.manifest.json +1 -1
- package/dist/{area-DSW_LYXQ.js → area-C_kgZZhN.js} +1 -1
- package/dist/{area-DSW_LYXQ.js.map → area-C_kgZZhN.js.map} +1 -1
- package/dist/{area-8IBAXzbC.cjs → area-DFPtKzWy.cjs} +1 -1
- package/dist/{area-8IBAXzbC.cjs.map → area-DFPtKzWy.cjs.map} +1 -1
- package/dist/area.cjs +1 -1
- package/dist/area.js +1 -1
- package/dist/{autocomplete-CXwwmUbC.js → autocomplete-DWSuwSRS.js} +2 -2
- package/dist/{autocomplete-CXwwmUbC.js.map → autocomplete-DWSuwSRS.js.map} +1 -1
- package/dist/{autocomplete-9PLjlFYt.cjs → autocomplete-iCJOia-q.cjs} +1 -1
- package/dist/{autocomplete-9PLjlFYt.cjs.map → autocomplete-iCJOia-q.cjs.map} +1 -1
- package/dist/autocomplete.cjs +1 -1
- package/dist/autocomplete.js +1 -1
- package/dist/avatar.cjs +1 -1
- package/dist/avatar.js +1 -1
- package/dist/badge.cjs +1 -1
- package/dist/badge.js +1 -1
- package/dist/{boat-Dwn5oXd8.js → boat-CZma2ojF.js} +1 -1
- package/dist/{boat-Dwn5oXd8.js.map → boat-CZma2ojF.js.map} +1 -1
- package/dist/{boat-CpGNeWav.cjs → boat-Dy6cc3hB.cjs} +1 -1
- package/dist/{boat-CpGNeWav.cjs.map → boat-Dy6cc3hB.cjs.map} +1 -1
- package/dist/boat.cjs +1 -1
- package/dist/boat.js +1 -1
- package/dist/breadcrumb.cjs +1 -1
- package/dist/breadcrumb.js +1 -1
- package/dist/{busy-CUUgvimY.cjs → busy-DCsqryvq.cjs} +1 -1
- package/dist/{busy-CUUgvimY.cjs.map → busy-DCsqryvq.cjs.map} +1 -1
- package/dist/{busy-Cjm1BYVC.js → busy-DeV2ByMw.js} +1 -1
- package/dist/{busy-Cjm1BYVC.js.map → busy-DeV2ByMw.js.map} +1 -1
- package/dist/busy.cjs +1 -1
- package/dist/busy.js +1 -1
- package/dist/button.cjs +1 -1
- package/dist/button.js +1 -1
- package/dist/{card-BjZ_WRr3.cjs → card--GgSX4X5.cjs} +1 -1
- package/dist/{card-BjZ_WRr3.cjs.map → card--GgSX4X5.cjs.map} +1 -1
- package/dist/{card-BR22oYCL.js → card-BTTsHzJJ.js} +1 -1
- package/dist/{card-BR22oYCL.js.map → card-BTTsHzJJ.js.map} +1 -1
- package/dist/card.cjs +1 -1
- package/dist/card.js +1 -1
- package/dist/{checkbox-CsADwyfu.js → checkbox-Cj5j-ppk.js} +1 -1
- package/dist/{checkbox-CsADwyfu.js.map → checkbox-Cj5j-ppk.js.map} +1 -1
- package/dist/{checkbox-2e8v7CNg.cjs → checkbox-NNReP9s_.cjs} +1 -1
- package/dist/{checkbox-2e8v7CNg.cjs.map → checkbox-NNReP9s_.cjs.map} +1 -1
- package/dist/checkbox.cjs +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/{chips-C9HwVbGT.js → chips-CP-CbfoZ.js} +2 -2
- package/dist/{chips-C9HwVbGT.js.map → chips-CP-CbfoZ.js.map} +1 -1
- package/dist/{chips-DPCcO55o.cjs → chips-iporOXxK.cjs} +1 -1
- package/dist/{chips-DPCcO55o.cjs.map → chips-iporOXxK.cjs.map} +1 -1
- package/dist/chips.cjs +1 -1
- package/dist/chips.js +2 -2
- package/dist/connectivity.cjs +1 -1
- package/dist/connectivity.js +1 -1
- package/dist/content-drawer.cjs +1 -1
- package/dist/content-drawer.js +1 -1
- package/dist/{date-range-63-FC7gD.cjs → date-range-CaOxwZDq.cjs} +1 -1
- package/dist/{date-range-63-FC7gD.cjs.map → date-range-CaOxwZDq.cjs.map} +1 -1
- package/dist/{date-range-CFaP-8Os.js → date-range-CgNujP8r.js} +2 -2
- package/dist/{date-range-CFaP-8Os.js.map → date-range-CgNujP8r.js.map} +1 -1
- package/dist/{date-range-inline-BCuK_XCv.js → date-range-inline-C2PXX_GY.js} +1 -1
- package/dist/{date-range-inline-BCuK_XCv.js.map → date-range-inline-C2PXX_GY.js.map} +1 -1
- package/dist/{date-range-inline-Cpdqd-8B.cjs → date-range-inline-D4IjOOO0.cjs} +1 -1
- package/dist/{date-range-inline-Cpdqd-8B.cjs.map → date-range-inline-D4IjOOO0.cjs.map} +1 -1
- package/dist/date-range-inline.cjs +1 -1
- package/dist/date-range-inline.js +1 -1
- package/dist/date-range.cjs +1 -1
- package/dist/date-range.js +1 -1
- package/dist/delay.cjs +1 -1
- package/dist/delay.js +1 -1
- package/dist/{details-qKikJIyH.cjs → details-DT2b3xOn.cjs} +1 -1
- package/dist/{details-qKikJIyH.cjs.map → details-DT2b3xOn.cjs.map} +1 -1
- package/dist/{details-0dOlqHHL.js → details-VjaNwtfd.js} +1 -1
- package/dist/{details-0dOlqHHL.js.map → details-VjaNwtfd.js.map} +1 -1
- package/dist/details.cjs +1 -1
- package/dist/details.js +1 -1
- package/dist/{divider-BxkIl0H1.js → divider-BMO8pzEO.js} +1 -1
- package/dist/{divider-BxkIl0H1.js.map → divider-BMO8pzEO.js.map} +1 -1
- package/dist/{divider-CX9mmWZ8.cjs → divider-BW33TZ-X.cjs} +1 -1
- package/dist/{divider-CX9mmWZ8.cjs.map → divider-BW33TZ-X.cjs.map} +1 -1
- package/dist/divider.cjs +1 -1
- package/dist/divider.js +1 -1
- package/dist/dropdown.cjs +1 -1
- package/dist/dropdown.js +1 -1
- package/dist/{expand-BeAx94MP.js → expand-DbELKKOt.js} +2 -2
- package/dist/{expand-BeAx94MP.js.map → expand-DbELKKOt.js.map} +1 -1
- package/dist/{expand-891JuQuN.cjs → expand-_f5EUKWB.cjs} +1 -1
- package/dist/{expand-891JuQuN.cjs.map → expand-_f5EUKWB.cjs.map} +1 -1
- package/dist/expand.cjs +1 -1
- package/dist/expand.js +1 -1
- package/dist/{float-BPF2WO4L.js → float-B6RBb2dN.js} +1 -1
- package/dist/{float-BPF2WO4L.js.map → float-B6RBb2dN.js.map} +1 -1
- package/dist/{float-D7vvODxx.cjs → float-CKmd-0-t.cjs} +1 -1
- package/dist/{float-D7vvODxx.cjs.map → float-CKmd-0-t.cjs.map} +1 -1
- package/dist/float.cjs +1 -1
- package/dist/float.js +1 -1
- package/dist/handover/agent-runtime-followups.md +1 -1
- package/dist/handover/agent-runtime-v1.md +3 -3
- package/dist/{icons-BKxW_7QR.js → icons-CoDo95Cu.js} +1 -1
- package/dist/{icons-BKxW_7QR.js.map → icons-CoDo95Cu.js.map} +1 -1
- package/dist/{icons-QSdo-8h9.cjs → icons-r-S17M8U.cjs} +1 -1
- package/dist/{icons-QSdo-8h9.cjs.map → icons-r-S17M8U.cjs.map} +1 -1
- package/dist/icons.cjs +1 -1
- package/dist/icons.js +1 -1
- package/dist/{iframe-CMKV-bm8.cjs → iframe-P9c_qg1-.cjs} +1 -1
- package/dist/{iframe-CMKV-bm8.cjs.map → iframe-P9c_qg1-.cjs.map} +1 -1
- package/dist/{iframe-BxvbhyTS.js → iframe-k4oI-TIj.js} +1 -1
- package/dist/{iframe-BxvbhyTS.js.map → iframe-k4oI-TIj.js.map} +1 -1
- package/dist/iframe.cjs +1 -1
- package/dist/iframe.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +23 -23
- package/dist/{input-DIqaR8Mr.js → input-D95GjINh.js} +1 -1
- package/dist/{input-DIqaR8Mr.js.map → input-D95GjINh.js.map} +1 -1
- package/dist/{input-BFhJU74_.cjs → input-D9s4jDAb.cjs} +1 -1
- package/dist/{input-BFhJU74_.cjs.map → input-D9s4jDAb.cjs.map} +1 -1
- package/dist/{input-chip-w09qTt7J.cjs → input-chip-D0ZXqTt5.cjs} +1 -1
- package/dist/{input-chip-w09qTt7J.cjs.map → input-chip-D0ZXqTt5.cjs.map} +1 -1
- package/dist/{input-chip-D9tlSk_2.js → input-chip-DpC_XEKN.js} +1 -1
- package/dist/{input-chip-D9tlSk_2.js.map → input-chip-DpC_XEKN.js.map} +1 -1
- package/dist/input.cjs +1 -1
- package/dist/input.js +1 -1
- package/dist/json.cjs +1 -1
- package/dist/json.js +2 -2
- package/dist/kbd.cjs +1 -1
- package/dist/kbd.js +1 -1
- package/dist/layout.cjs +1 -1
- package/dist/layout.js +1 -1
- package/dist/{lightbox-CK035jsx.cjs → lightbox-C-yHeoK0.cjs} +1 -1
- package/dist/{lightbox-CK035jsx.cjs.map → lightbox-C-yHeoK0.cjs.map} +1 -1
- package/dist/{lightbox-GChmL3Ff.js → lightbox-CovQtmyn.js} +1 -1
- package/dist/{lightbox-GChmL3Ff.js.map → lightbox-CovQtmyn.js.map} +1 -1
- package/dist/lightbox.cjs +1 -1
- package/dist/lightbox.js +1 -1
- package/dist/{list-J-Fz24Z1.js → list-C1pR9vhu.js} +1 -1
- package/dist/{list-J-Fz24Z1.js.map → list-C1pR9vhu.js.map} +1 -1
- package/dist/{list-B3P37zlH.cjs → list-CAijuky4.cjs} +1 -1
- package/dist/{list-B3P37zlH.cjs.map → list-CAijuky4.cjs.map} +1 -1
- package/dist/list.cjs +1 -1
- package/dist/list.js +1 -1
- package/dist/{menu-DHTlUwXS.js → menu-B59vZv9n.js} +2 -2
- package/dist/{menu-DHTlUwXS.js.map → menu-B59vZv9n.js.map} +1 -1
- package/dist/{menu-BnFd8CwU.cjs → menu-BaHO3Cip.cjs} +1 -1
- package/dist/{menu-BnFd8CwU.cjs.map → menu-BaHO3Cip.cjs.map} +1 -1
- package/dist/menu.cjs +1 -1
- package/dist/menu.js +1 -1
- package/dist/mixins-BV0w2yIE.js +627 -0
- package/dist/{mixins-PBJJGiiP.js.map → mixins-BV0w2yIE.js.map} +1 -1
- package/dist/mixins-DvAYa-F7.cjs +298 -0
- package/dist/{mixins-47_CZk7q.cjs.map → mixins-DvAYa-F7.cjs.map} +1 -1
- package/dist/mixins.cjs +1 -1
- package/dist/mixins.js +1 -1
- package/dist/nav-drawer.cjs +1 -1
- package/dist/nav-drawer.js +1 -1
- package/dist/navigation-bar.cjs +1 -1
- package/dist/navigation-bar.js +1 -1
- package/dist/navigation-rail.cjs +1 -1
- package/dist/navigation-rail.js +1 -1
- package/dist/{notification-B6YBL0hx.cjs → notification-BC9nG8Sr.cjs} +1 -1
- package/dist/{notification-B6YBL0hx.cjs.map → notification-BC9nG8Sr.cjs.map} +1 -1
- package/dist/{notification-C-5Bv3vj.js → notification-BeLoVa47.js} +2 -2
- package/dist/{notification-C-5Bv3vj.js.map → notification-BeLoVa47.js.map} +1 -1
- package/dist/notification.cjs +1 -1
- package/dist/notification.js +1 -1
- package/dist/{option-DVQRa3nr.cjs → option-BWF4GBp-.cjs} +1 -1
- package/dist/{option-DVQRa3nr.cjs.map → option-BWF4GBp-.cjs.map} +1 -1
- package/dist/{option-B7q6VXCu.js → option-UvlSAcC4.js} +1 -1
- package/dist/{option-B7q6VXCu.js.map → option-UvlSAcC4.js.map} +1 -1
- package/dist/option.cjs +1 -1
- package/dist/option.js +1 -1
- package/dist/overlay.cjs +1 -1
- package/dist/{overlay.confirm-body-CAY5xK1n.js → overlay.confirm-body-9W0B5QGv.js} +1 -1
- package/dist/{overlay.confirm-body-CAY5xK1n.js.map → overlay.confirm-body-9W0B5QGv.js.map} +1 -1
- package/dist/{overlay.confirm-body-XZtErofy.cjs → overlay.confirm-body-URtE1gI3.cjs} +1 -1
- package/dist/{overlay.confirm-body-XZtErofy.cjs.map → overlay.confirm-body-URtE1gI3.cjs.map} +1 -1
- package/dist/overlay.js +3 -3
- package/dist/{overlay.service-BZE_lwKO.js → overlay.service-CVqs2Gu1.js} +2 -2
- package/dist/{overlay.service-BZE_lwKO.js.map → overlay.service-CVqs2Gu1.js.map} +1 -1
- package/dist/{overlay.service-Oyjrw831.cjs → overlay.service-DnZTcKyJ.cjs} +1 -1
- package/dist/{overlay.service-Oyjrw831.cjs.map → overlay.service-DnZTcKyJ.cjs.map} +1 -1
- package/dist/page.cjs +1 -1
- package/dist/page.js +2 -2
- package/dist/{progress-BHXLYs9i.js → progress-C29Uw-WJ.js} +1 -1
- package/dist/{progress-BHXLYs9i.js.map → progress-C29Uw-WJ.js.map} +1 -1
- package/dist/{progress-D99bumkC.cjs → progress-CwzwY8Oe.cjs} +1 -1
- package/dist/{progress-D99bumkC.cjs.map → progress-CwzwY8Oe.cjs.map} +1 -1
- package/dist/progress.cjs +1 -1
- package/dist/progress.js +1 -1
- package/dist/{radio-group-DYsycLmD.cjs → radio-group-ByMD6Lsj.cjs} +1 -1
- package/dist/{radio-group-DYsycLmD.cjs.map → radio-group-ByMD6Lsj.cjs.map} +1 -1
- package/dist/{radio-group-BYra5_q1.js → radio-group-CW8airhZ.js} +1 -1
- package/dist/{radio-group-BYra5_q1.js.map → radio-group-CW8airhZ.js.map} +1 -1
- package/dist/radio-group.cjs +1 -1
- package/dist/radio-group.js +1 -1
- package/dist/range.cjs +1 -1
- package/dist/range.js +1 -1
- package/dist/{scroll-TqNWZ0lo.js → scroll-BotoGcMU.js} +1 -1
- package/dist/{scroll-TqNWZ0lo.js.map → scroll-BotoGcMU.js.map} +1 -1
- package/dist/{scroll-cayCBOrq.cjs → scroll-CmhmUebp.cjs} +1 -1
- package/dist/{scroll-cayCBOrq.cjs.map → scroll-CmhmUebp.cjs.map} +1 -1
- package/dist/{select-CRdSmlLq.cjs → select-BdBThja4.cjs} +1 -1
- package/dist/{select-CRdSmlLq.cjs.map → select-BdBThja4.cjs.map} +1 -1
- package/dist/{select-nzq0qFlF.js → select-Dbn-CImU.js} +1 -1
- package/dist/{select-nzq0qFlF.js.map → select-Dbn-CImU.js.map} +1 -1
- package/dist/select.cjs +1 -1
- package/dist/select.js +1 -1
- package/dist/skeleton.cjs +1 -1
- package/dist/skeleton.js +1 -1
- package/dist/skills/schmancy/state.md +0 -26
- package/dist/skills/state.md +0 -26
- package/dist/slider.cjs +1 -1
- package/dist/slider.js +1 -1
- package/dist/{splash-screen-BMLQXzDq.cjs → splash-screen-DlQUv-kV.cjs} +1 -1
- package/dist/{splash-screen-BMLQXzDq.cjs.map → splash-screen-DlQUv-kV.cjs.map} +1 -1
- package/dist/{splash-screen-BJeIiJ_e.js → splash-screen-DtkjCJYo.js} +1 -1
- package/dist/{splash-screen-BJeIiJ_e.js.map → splash-screen-DtkjCJYo.js.map} +1 -1
- package/dist/splash-screen.cjs +1 -1
- package/dist/splash-screen.js +1 -1
- package/dist/{src-qvWlNoMO.js → src-D6e0adHi.js} +30 -30
- package/dist/{src-qvWlNoMO.js.map → src-D6e0adHi.js.map} +1 -1
- package/dist/{src-DE11tq2Q.cjs → src-DEUjlTsX.cjs} +1 -1
- package/dist/{src-DE11tq2Q.cjs.map → src-DEUjlTsX.cjs.map} +1 -1
- package/dist/steps.cjs +1 -1
- package/dist/steps.js +1 -1
- package/dist/{surface-DG7Cmm9V.js → surface-A82O1kgu.js} +1 -1
- package/dist/{surface-DG7Cmm9V.js.map → surface-A82O1kgu.js.map} +1 -1
- package/dist/{surface-D426MFLR.cjs → surface-BpppoNXN.cjs} +1 -1
- package/dist/{surface-D426MFLR.cjs.map → surface-BpppoNXN.cjs.map} +1 -1
- package/dist/surface.cjs +1 -1
- package/dist/surface.js +1 -1
- package/dist/switch.cjs +1 -1
- package/dist/switch.js +1 -1
- package/dist/table.cjs +1 -1
- package/dist/table.js +1 -1
- package/dist/{tabs-t3nMfg1F.cjs → tabs-TO3UiBsm.cjs} +1 -1
- package/dist/{tabs-t3nMfg1F.cjs.map → tabs-TO3UiBsm.cjs.map} +1 -1
- package/dist/{tabs-B7siJkM5.js → tabs-cVHHd1dY.js} +1 -1
- package/dist/{tabs-B7siJkM5.js.map → tabs-cVHHd1dY.js.map} +1 -1
- package/dist/tabs.cjs +1 -1
- package/dist/tabs.js +1 -1
- package/dist/teleport.cjs +1 -1
- package/dist/teleport.js +1 -1
- package/dist/{textarea-DSxHCCle.js → textarea-B9dy-yec.js} +1 -1
- package/dist/{textarea-DSxHCCle.js.map → textarea-B9dy-yec.js.map} +1 -1
- package/dist/{textarea-o9vysorM.cjs → textarea-DFY0Flgv.cjs} +1 -1
- package/dist/{textarea-o9vysorM.cjs.map → textarea-DFY0Flgv.cjs.map} +1 -1
- package/dist/textarea.cjs +1 -1
- package/dist/textarea.js +1 -1
- package/dist/{theme-XO3nHDbW.js → theme-CT408FqH.js} +1 -1
- package/dist/{theme-XO3nHDbW.js.map → theme-CT408FqH.js.map} +1 -1
- package/dist/{theme-Ce9eIP05.cjs → theme-CpuF3D3q.cjs} +1 -1
- package/dist/{theme-Ce9eIP05.cjs.map → theme-CpuF3D3q.cjs.map} +1 -1
- package/dist/{theme-button-H7PRz_bg.cjs → theme-button-B6Xf-EiH.cjs} +1 -1
- package/dist/{theme-button-H7PRz_bg.cjs.map → theme-button-B6Xf-EiH.cjs.map} +1 -1
- package/dist/{theme-button-DNutDO1j.js → theme-button-pTb5-Wxx.js} +1 -1
- package/dist/{theme-button-DNutDO1j.js.map → theme-button-pTb5-Wxx.js.map} +1 -1
- package/dist/theme-button.cjs +1 -1
- package/dist/theme-button.js +1 -1
- package/dist/theme.cjs +1 -1
- package/dist/theme.js +2 -2
- package/dist/tree.cjs +1 -1
- package/dist/tree.js +1 -1
- package/dist/typography.cjs +1 -1
- package/dist/typography.js +1 -1
- package/dist/visually-hidden.cjs +1 -1
- package/dist/visually-hidden.js +1 -1
- package/dist/{window-BaoSwgGE.cjs → window-CSKvv4Ts.cjs} +1 -1
- package/dist/{window-BaoSwgGE.cjs.map → window-CSKvv4Ts.cjs.map} +1 -1
- package/dist/{window-KnLWhQ3S.js → window-CuBcOxbc.js} +1 -1
- package/dist/{window-KnLWhQ3S.js.map → window-CuBcOxbc.js.map} +1 -1
- package/dist/window.cjs +1 -1
- package/dist/window.js +1 -1
- package/package.json +1 -1
- package/skills/schmancy/state.md +0 -26
- package/src/CLAUDE.md +1 -5
- package/src/state/CLAUDE.md +0 -2
- package/dist/mixins-47_CZk7q.cjs +0 -298
- package/dist/mixins-PBJJGiiP.js +0 -627
- package/src/state/MIGRATION.md +0 -258
package/src/state/MIGRATION.md
DELETED
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
# Migrating from `createContext` to `state()`
|
|
2
|
-
|
|
3
|
-
Cheatsheet for moving call sites off the v1 `createContext` /
|
|
4
|
-
`@select` / `createCompoundSelector` / `selectItem` family to
|
|
5
|
-
`@mhmo91/schmancy/state`.
|
|
6
|
-
|
|
7
|
-
The v1 surface has been deleted from `@mhmo91/schmancy`. There is no
|
|
8
|
-
parallel API; every consumer needs to switch.
|
|
9
|
-
|
|
10
|
-
## Imports
|
|
11
|
-
|
|
12
|
-
```ts
|
|
13
|
-
// Before
|
|
14
|
-
import { createContext, select, selectItem, createCompoundSelector } from '@mhmo91/schmancy'
|
|
15
|
-
|
|
16
|
-
// After
|
|
17
|
-
import { state, computed, observe, bindState, stateFromObservable } from '@mhmo91/schmancy/state'
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## Defining a state
|
|
21
|
-
|
|
22
|
-
| v1 | v2 |
|
|
23
|
-
|---|---|
|
|
24
|
-
| `createContext<T>(initial, 'memory', 'foo')` | `state<T>('feature/foo').memory(initial)` |
|
|
25
|
-
| `createContext<T>(initial, 'session', 'foo')` | `state<T>('feature/foo').session(initial)` |
|
|
26
|
-
| `createContext<T>(initial, 'local', 'foo')` | `state<T>('feature/foo').local(initial)` |
|
|
27
|
-
| `createContext<T>(initial, 'indexeddb', 'foo')` | `state<T>('feature/foo').idb(initial)` |
|
|
28
|
-
|
|
29
|
-
The string namespace replaces the v1 third-argument storage key. It
|
|
30
|
-
must contain a `/` (compile-time enforced via the
|
|
31
|
-
`${string}/${string}` template literal). Storage is keyed off the
|
|
32
|
-
namespace string.
|
|
33
|
-
|
|
34
|
-
If your file already declares the initial value in a typed const, drop
|
|
35
|
-
the type arg:
|
|
36
|
-
|
|
37
|
-
```ts
|
|
38
|
-
const initial: CartState = { items: [], total: 0 }
|
|
39
|
-
const cart = state('hannah/cart').session(initial) // T inferred from `initial`
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Reading
|
|
43
|
-
|
|
44
|
-
| v1 | v2 |
|
|
45
|
-
|---|---|
|
|
46
|
-
| `cart.value` | `cart.value` (unchanged) |
|
|
47
|
-
| `cart.$.subscribe(...)` | `cart.$.subscribe(...)` (unchanged) |
|
|
48
|
-
| `cart.ready` (boolean) | `cart.loaded` (boolean) + `await cart.ready` (Promise<void>) |
|
|
49
|
-
|
|
50
|
-
`cart.ready` is now a Promise that resolves when initial load completes
|
|
51
|
-
(success or fallback). `cart.loaded` is the boolean runtime flag. Use
|
|
52
|
-
whichever fits the call site.
|
|
53
|
-
|
|
54
|
-
## Writing
|
|
55
|
-
|
|
56
|
-
| v1 | v2 |
|
|
57
|
-
|---|---|
|
|
58
|
-
| `cart.set({ total: 12 })` | `cart.set({ total: 12 })` (unchanged) |
|
|
59
|
-
| `cart.set({ items: [] }, false)` | `cart.set({ items: [] }, false)` (unchanged) |
|
|
60
|
-
| `cart.replace(next)` | `cart.replace(next)` (unchanged) |
|
|
61
|
-
| `cart.delete('total')` | `cart.delete('total')` (unchanged) |
|
|
62
|
-
| Manual `replace({ ...current, ...patch })` cascade | `cart.update(d => { … })` — immer recipe, single notification |
|
|
63
|
-
|
|
64
|
-
For `Map<K, V>` shapes:
|
|
65
|
-
|
|
66
|
-
| v1 | v2 |
|
|
67
|
-
|---|---|
|
|
68
|
-
| `docs.set('id', doc)` | `docs.set('id', doc)` (unchanged — MapAPI dispatch) |
|
|
69
|
-
|
|
70
|
-
For `Set<U>`:
|
|
71
|
-
|
|
72
|
-
| v1 | v2 |
|
|
73
|
-
|---|---|
|
|
74
|
-
| Manual `replace(new Set([...current, item]))` | `sel.add('item')` |
|
|
75
|
-
| Manual replace-without-item | `sel.delete('item')` (returns boolean) |
|
|
76
|
-
| | `sel.toggle('item')` (new) |
|
|
77
|
-
|
|
78
|
-
For arrays:
|
|
79
|
-
|
|
80
|
-
| v1 | v2 |
|
|
81
|
-
|---|---|
|
|
82
|
-
| `array.push(...items)` | `array.push(...items)` (unchanged) |
|
|
83
|
-
| Manual `replace(current.filter(...))` | `array.update(d => d.splice(...))` (immer) |
|
|
84
|
-
|
|
85
|
-
For nullable references and primitives:
|
|
86
|
-
|
|
87
|
-
| v1 | v2 |
|
|
88
|
-
|---|---|
|
|
89
|
-
| `editing.set({ id: 'x' })` then `editing.set(null)` | Same (ScalarAPI accepts the union directly) |
|
|
90
|
-
|
|
91
|
-
## Subscribing in a component
|
|
92
|
-
|
|
93
|
-
The v1 `@select` decorator is gone. Three options in v2, in order of
|
|
94
|
-
preference:
|
|
95
|
-
|
|
96
|
-
### (1) Default — direct read in render (zero ceremony)
|
|
97
|
-
|
|
98
|
-
`$LitElement()` composes `SignalWatcher`, so signal reads in `render()`
|
|
99
|
-
auto-track. Just import the state and use it inline:
|
|
100
|
-
|
|
101
|
-
```ts
|
|
102
|
-
@customElement('cart-view')
|
|
103
|
-
class CartView extends $LitElement() {
|
|
104
|
-
render() { return html`Items: ${cart.value.items.length}` }
|
|
105
|
-
}
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
No decorator, no field, no binding code. The imported `cart` singleton
|
|
109
|
-
IS the binding.
|
|
110
|
-
|
|
111
|
-
### (2) `@observe(source)` — when you need a class field
|
|
112
|
-
|
|
113
|
-
```ts
|
|
114
|
-
class CartView extends $LitElement() {
|
|
115
|
-
@observe(cart) cart!: CartState
|
|
116
|
-
|
|
117
|
-
onClick() {
|
|
118
|
-
console.log(this.cart) // event handler needs `this.cart`
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
render() {
|
|
122
|
-
return html`Items: ${this.cart.items.length}`
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
Reads return the latest value. Caller writes are dropped with a dev
|
|
128
|
-
warning. Same decorator shape as `@property` — works under the existing
|
|
129
|
-
tsconfig.
|
|
130
|
-
|
|
131
|
-
### (3) `bindState(host, source)` — for hosts that aren't `$LitElement`
|
|
132
|
-
|
|
133
|
-
```ts
|
|
134
|
-
class CustomHost extends LitElement {
|
|
135
|
-
cart = bindState(this, cart)
|
|
136
|
-
render() { return html`Items: ${this.cart.value.items.length}` }
|
|
137
|
-
}
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
## Compound selectors → `computed`
|
|
141
|
-
|
|
142
|
-
```ts
|
|
143
|
-
// Before
|
|
144
|
-
const cartItemCount = createCompoundSelector(
|
|
145
|
-
[cartContext],
|
|
146
|
-
[cart => cart.items.length],
|
|
147
|
-
count => count,
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
// After
|
|
151
|
-
import { computed } from '@mhmo91/schmancy/state'
|
|
152
|
-
const cartItemCount = computed(() => cart.value.items.length)
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
Cross-state composition just works:
|
|
156
|
-
|
|
157
|
-
```ts
|
|
158
|
-
const orderTotal = computed(() => cart.value.subtotal + tip.value.amount)
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
Reading any `state.value` inside `computed(fn)` auto-tracks. No
|
|
162
|
-
explicit dependency array.
|
|
163
|
-
|
|
164
|
-
## Side effects → `effect`
|
|
165
|
-
|
|
166
|
-
```ts
|
|
167
|
-
import { effect } from '@mhmo91/schmancy/state'
|
|
168
|
-
|
|
169
|
-
const stop = effect(() => {
|
|
170
|
-
document.title = `${cart.value.items.length} items`
|
|
171
|
-
})
|
|
172
|
-
|
|
173
|
-
// later, when no longer needed:
|
|
174
|
-
stop[Symbol.dispose]()
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
Eager run + microtask-coalesced re-runs. Returns a `Disposable`.
|
|
178
|
-
|
|
179
|
-
## Observable bridges
|
|
180
|
-
|
|
181
|
-
```ts
|
|
182
|
-
// Before
|
|
183
|
-
const userPresence$ = new BehaviorSubject({ online: false, since: 0 })
|
|
184
|
-
// (read with .value, subscribe with .$, no persistence story)
|
|
185
|
-
|
|
186
|
-
// After
|
|
187
|
-
import { stateFromObservable } from '@mhmo91/schmancy/state'
|
|
188
|
-
|
|
189
|
-
const userPresence = stateFromObservable(
|
|
190
|
-
presence$, // Observable<PresenceState>
|
|
191
|
-
'app/presence',
|
|
192
|
-
{ online: false, since: 0 },
|
|
193
|
-
)
|
|
194
|
-
// userPresence has .value, .$, all variant API methods, lifecycle.
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
## Lifecycle / disposal
|
|
198
|
-
|
|
199
|
-
```ts
|
|
200
|
-
// Module scope — same as v1
|
|
201
|
-
export const cart = state('hannah/cart').session(initial)
|
|
202
|
-
|
|
203
|
-
// Test scope — using
|
|
204
|
-
it('cart updates total on add', () => {
|
|
205
|
-
using cart = state('test/cart').memory(initial)
|
|
206
|
-
cart.update(d => { d.items.push(item) })
|
|
207
|
-
expect(cart.value.total).toBe(item.price)
|
|
208
|
-
}) // [Symbol.dispose] runs here, even on assertion failure
|
|
209
|
-
|
|
210
|
-
// IDB-backed in tests — await using flushes pending writes
|
|
211
|
-
it('persists across reloads', async () => {
|
|
212
|
-
await using cart = state('test/cart').idb(initial)
|
|
213
|
-
// ...
|
|
214
|
-
})
|
|
215
|
-
|
|
216
|
-
// Imperative cleanup (samwa back-compat alias)
|
|
217
|
-
cart.destroy()
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
## Things that went away
|
|
221
|
-
|
|
222
|
-
- **`createCompoundSelector`** — use `computed()`.
|
|
223
|
-
- **`@select` and `@selectItem` decorators** — use direct render reads
|
|
224
|
-
via `$LitElement` (default), `@observe` (field-level), or `bindState`
|
|
225
|
-
(non-Lit hosts).
|
|
226
|
-
- **`IStore` / `ICollectionStore` / `IArrayStore` interfaces** — no
|
|
227
|
-
longer needed. The variant write API dispatch is type-level.
|
|
228
|
-
- **`error$` per-store Subject** — errors flow through console + the
|
|
229
|
-
`StateStorageError` thrown from `save()` for IDB write failures.
|
|
230
|
-
- **Tree-scoped `<state-provider>`** — replaced by
|
|
231
|
-
`<schmancy-context provides={[…]}>`. Same intent (per-subtree
|
|
232
|
-
isolation of a state), different API: in v1 the provider was a
|
|
233
|
-
primitive; in v2 the state surface stays unchanged and the
|
|
234
|
-
`<schmancy-context>` element is what scopes a subtree. Consumer
|
|
235
|
-
code (`cart.value`, `cart.set(...)`) is identical inside and
|
|
236
|
-
outside the element. See `SCOPING.md` for the details.
|
|
237
|
-
|
|
238
|
-
## Footguns
|
|
239
|
-
|
|
240
|
-
- **Don't use `using` at module scope.** It disposes on module GC,
|
|
241
|
-
which is roughly never until the tab closes. Plain `const` for
|
|
242
|
-
module singletons, `using` for test/function scope only.
|
|
243
|
-
- **Namespaces always contain `/`.** `state('cart')` is a TypeError;
|
|
244
|
-
use `state('feature/cart')`.
|
|
245
|
-
- **Don't `state.signal.set(...)` directly.** Go through the variant
|
|
246
|
-
API so write-coalescing and persistence stay coherent.
|
|
247
|
-
- **Inline literals without a typed const narrow T.**
|
|
248
|
-
`state('app/x').memory({ items: [], total: 0 })` infers
|
|
249
|
-
`{ items: never[]; total: number }`. Either use a typed const first
|
|
250
|
-
or pass the type arg: `state<CartState>('app/x').memory({...})`.
|
|
251
|
-
|
|
252
|
-
## Pointers
|
|
253
|
-
|
|
254
|
-
- Skill / API reference: `packages/schmancy/skills/schmancy/state.md`
|
|
255
|
-
- Agent brief: `packages/schmancy/src/state/CLAUDE.md`
|
|
256
|
-
- Tree-scoping reference: `packages/schmancy/src/state/SCOPING.md`
|
|
257
|
-
- Original plan: `~/.claude/plans/indexed-twirling-stroustrup.md`
|
|
258
|
-
- Scoping plan: `~/.claude/plans/federated-petting-penguin.md`
|