@blac/core 2.1.0 → 2.1.2
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 +19 -29
- package/dist/StateContainer-BUyuxKb3.cjs +667 -0
- package/dist/StateContainer-BUyuxKb3.cjs.map +1 -0
- package/dist/StateContainer-B_7UHc3I.js +632 -0
- package/dist/StateContainer-B_7UHc3I.js.map +1 -0
- package/dist/StateContainer-Bh2ipNYj.js +632 -0
- package/dist/StateContainer-Bh2ipNYj.js.map +1 -0
- package/dist/StateContainer-ClzwKnQZ.cjs +667 -0
- package/dist/StateContainer-ClzwKnQZ.cjs.map +1 -0
- package/dist/StateContainer-CwByTd5L.js +656 -0
- package/dist/StateContainer-CwByTd5L.js.map +1 -0
- package/dist/StateContainer-D2b10eR4.cjs +691 -0
- package/dist/StateContainer-D2b10eR4.cjs.map +1 -0
- package/dist/StateContainer-DiQATvZh.js +632 -0
- package/dist/StateContainer-DiQATvZh.js.map +1 -0
- package/dist/StateContainer-j16zciex.cjs +667 -0
- package/dist/StateContainer-j16zciex.cjs.map +1 -0
- package/dist/{StateContainerRegistry-CSNm2Ws5.cjs → StateContainerRegistry-141uHhtF.cjs} +300 -397
- package/dist/StateContainerRegistry-141uHhtF.cjs.map +1 -0
- package/dist/StateContainerRegistry-B6O6cfJd.cjs +903 -0
- package/dist/StateContainerRegistry-B6O6cfJd.cjs.map +1 -0
- package/dist/{StateContainerRegistry-DVIBTxGZ.js → StateContainerRegistry-BH7aOMWV.js} +299 -406
- package/dist/StateContainerRegistry-BH7aOMWV.js.map +1 -0
- package/dist/StateContainerRegistry-BX-DlHXO.js +747 -0
- package/dist/StateContainerRegistry-BX-DlHXO.js.map +1 -0
- package/dist/StateContainerRegistry-Bf5VuVjm.js +747 -0
- package/dist/StateContainerRegistry-Bf5VuVjm.js.map +1 -0
- package/dist/{StateContainerRegistry-Dj77cok9.js → StateContainerRegistry-BsH_s0pJ.js} +303 -413
- package/dist/StateContainerRegistry-BsH_s0pJ.js.map +1 -0
- package/dist/StateContainerRegistry-BvSRfhKv.cjs +866 -0
- package/dist/StateContainerRegistry-BvSRfhKv.cjs.map +1 -0
- package/dist/StateContainerRegistry-C8jxrcqk.cjs +866 -0
- package/dist/StateContainerRegistry-C8jxrcqk.cjs.map +1 -0
- package/dist/{StateContainerRegistry-lIwo-0m3.cjs → StateContainerRegistry-CBLeHObO.cjs} +326 -418
- package/dist/StateContainerRegistry-CBLeHObO.cjs.map +1 -0
- package/dist/StateContainerRegistry-CrTtRX5V.js +772 -0
- package/dist/StateContainerRegistry-CrTtRX5V.js.map +1 -0
- package/dist/StateContainerRegistry-DjQQtlCW.cjs +870 -0
- package/dist/StateContainerRegistry-DjQQtlCW.cjs.map +1 -0
- package/dist/{StateContainerRegistry-D9BIRjwv.cjs → StateContainerRegistry-MkT0W4C2.cjs} +322 -411
- package/dist/StateContainerRegistry-MkT0W4C2.cjs.map +1 -0
- package/dist/StateContainerRegistry-gQbEutkN.js +751 -0
- package/dist/StateContainerRegistry-gQbEutkN.js.map +1 -0
- package/dist/{StateContainerRegistry-CvBOhAT2.js → StateContainerRegistry-vWgsD-RP.js} +277 -392
- package/dist/StateContainerRegistry-vWgsD-RP.js.map +1 -0
- package/dist/config.d.cts +8 -8
- package/dist/config.d.ts +8 -8
- package/dist/constants.d.cts +20 -28
- package/dist/constants.d.ts +20 -28
- package/dist/core/Cubit.d.ts +14 -10
- package/dist/core/StateContainer.d.ts +89 -62
- package/dist/core/StateContainerRegistry.d.ts +89 -166
- package/dist/core/meta.d.ts +37 -47
- package/dist/core/onActivated.d.ts +10 -0
- package/dist/core/symbols.d.ts +26 -1
- package/dist/decorators/blac.d.ts +38 -28
- package/dist/{acquire-B1LYXSGj.js → ensure-Bi_yXk6f.js} +16 -5
- package/dist/ensure-Bi_yXk6f.js.map +1 -0
- package/dist/{ensure-r1C_7K6_.cjs → ensure-BjhbDW8Z.cjs} +203 -160
- package/dist/ensure-BjhbDW8Z.cjs.map +1 -0
- package/dist/{ensure-BSJHkUNX.js → ensure-BnVyd6s4.js} +297 -122
- package/dist/ensure-BnVyd6s4.js.map +1 -0
- package/dist/{acquire-BZIs6tpN.cjs → ensure-Bx41d-il.cjs} +23 -6
- package/dist/ensure-Bx41d-il.cjs.map +1 -0
- package/dist/{acquire-BRIJVJaA.js → ensure-C7UQ_mKM.js} +16 -5
- package/dist/ensure-C7UQ_mKM.js.map +1 -0
- package/dist/{ensure-B59ri8oo.js → ensure-CneMkpbI.js} +298 -122
- package/dist/ensure-CneMkpbI.js.map +1 -0
- package/dist/{acquire-BdsVZBSe.js → ensure-CwtQVTam.js} +16 -5
- package/dist/ensure-CwtQVTam.js.map +1 -0
- package/dist/{ensure-B2DYCbbI.cjs → ensure-D15vGnk5.cjs} +328 -123
- package/dist/ensure-D15vGnk5.cjs.map +1 -0
- package/dist/{acquire-B1Wuqla6.cjs → ensure-D1D4WjYf.cjs} +23 -6
- package/dist/ensure-D1D4WjYf.cjs.map +1 -0
- package/dist/{ensure-BKdq5xsY.cjs → ensure-D3w6YGp9.cjs} +329 -123
- package/dist/ensure-D3w6YGp9.cjs.map +1 -0
- package/dist/{acquire-BJ3xUEmh.cjs → ensure-DBnuRJ0R.cjs} +23 -6
- package/dist/ensure-DBnuRJ0R.cjs.map +1 -0
- package/dist/{acquire-B_p1fNEh.cjs → ensure-DShrbIYY.cjs} +23 -6
- package/dist/ensure-DShrbIYY.cjs.map +1 -0
- package/dist/{acquire-BP-ZfUH2.js → ensure-NTB9nnnj.js} +16 -5
- package/dist/ensure-NTB9nnnj.js.map +1 -0
- package/dist/{ensure-D3WWWwMo.cjs → ensure-ORVw-WRE.cjs} +194 -155
- package/dist/ensure-ORVw-WRE.cjs.map +1 -0
- package/dist/{ensure-BEeY5Ab7.js → ensure-dsqWhIuO.js} +182 -147
- package/dist/ensure-dsqWhIuO.js.map +1 -0
- package/dist/{ensure-11-asM1e.js → ensure-k-6q7O25.js} +173 -150
- package/dist/ensure-k-6q7O25.js.map +1 -0
- package/dist/index.cjs +257 -86
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -13
- package/dist/index.d.ts +6 -13
- package/dist/index.js +232 -52
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +10 -0
- package/dist/internal.d.cts +8 -0
- package/dist/internal.d.ts +8 -0
- package/dist/internal.js +3 -0
- package/dist/plugin/BlacPlugin.d.ts +25 -25
- package/dist/plugin/PluginManager.d.ts +46 -59
- package/dist/plugins.cjs +383 -3
- package/dist/plugins.cjs.map +1 -0
- package/dist/plugins.d.cts +10 -5
- package/dist/plugins.d.ts +10 -5
- package/dist/plugins.js +381 -1
- package/dist/plugins.js.map +1 -0
- package/dist/registry/acquire.d.ts +2 -2
- package/dist/registry/config.d.ts +12 -0
- package/dist/registry/index.d.ts +2 -2
- package/dist/registry/management.d.ts +5 -0
- package/dist/registry/queries.d.ts +15 -0
- package/dist/registry/release.d.ts +4 -20
- package/dist/testing.cjs +63 -38
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +14 -12
- package/dist/testing.d.ts +14 -12
- package/dist/testing.js +53 -29
- package/dist/testing.js.map +1 -1
- package/dist/types/branded.d.ts +6 -13
- package/dist/types/utilities.d.ts +40 -31
- package/dist/utils/idGenerator.d.ts +6 -13
- package/dist/utils/static-props.d.ts +28 -29
- package/dist/utils/structural-key.d.ts +0 -22
- package/dist/watch/index.d.ts +1 -2
- package/dist/watch/watch.d.ts +23 -3
- package/package.json +28 -54
- package/dist/StateContainerRegistry-4Ljd9EJx.js +0 -1018
- package/dist/StateContainerRegistry-4Ljd9EJx.js.map +0 -1
- package/dist/StateContainerRegistry-8zNFMAf7.js +0 -1067
- package/dist/StateContainerRegistry-8zNFMAf7.js.map +0 -1
- package/dist/StateContainerRegistry-B1GYx9Xo.js +0 -975
- package/dist/StateContainerRegistry-B1GYx9Xo.js.map +0 -1
- package/dist/StateContainerRegistry-B_ViBLvJ.js +0 -975
- package/dist/StateContainerRegistry-B_ViBLvJ.js.map +0 -1
- package/dist/StateContainerRegistry-Bx2ly-ba.cjs +0 -1162
- package/dist/StateContainerRegistry-Bx2ly-ba.cjs.map +0 -1
- package/dist/StateContainerRegistry-C0dCNlTF.js +0 -1005
- package/dist/StateContainerRegistry-C0dCNlTF.js.map +0 -1
- package/dist/StateContainerRegistry-C75QpeaO.cjs +0 -1260
- package/dist/StateContainerRegistry-C75QpeaO.cjs.map +0 -1
- package/dist/StateContainerRegistry-CEWpc1bj.cjs +0 -1113
- package/dist/StateContainerRegistry-CEWpc1bj.cjs.map +0 -1
- package/dist/StateContainerRegistry-CS18y4au.cjs +0 -1163
- package/dist/StateContainerRegistry-CS18y4au.cjs.map +0 -1
- package/dist/StateContainerRegistry-CSNm2Ws5.cjs.map +0 -1
- package/dist/StateContainerRegistry-CchRjnjX.cjs +0 -1094
- package/dist/StateContainerRegistry-CchRjnjX.cjs.map +0 -1
- package/dist/StateContainerRegistry-CvBOhAT2.js.map +0 -1
- package/dist/StateContainerRegistry-D8nu7Z0T.js +0 -1068
- package/dist/StateContainerRegistry-D8nu7Z0T.js.map +0 -1
- package/dist/StateContainerRegistry-D9BIRjwv.cjs.map +0 -1
- package/dist/StateContainerRegistry-DJQqLrli.cjs +0 -1046
- package/dist/StateContainerRegistry-DJQqLrli.cjs.map +0 -1
- package/dist/StateContainerRegistry-DL5Ai7wh.js +0 -1153
- package/dist/StateContainerRegistry-DL5Ai7wh.js.map +0 -1
- package/dist/StateContainerRegistry-DVIBTxGZ.js.map +0 -1
- package/dist/StateContainerRegistry-DWOzx7Gd.js +0 -1154
- package/dist/StateContainerRegistry-DWOzx7Gd.js.map +0 -1
- package/dist/StateContainerRegistry-Dj77cok9.js.map +0 -1
- package/dist/StateContainerRegistry-FWKzPfS-.cjs +0 -1046
- package/dist/StateContainerRegistry-FWKzPfS-.cjs.map +0 -1
- package/dist/StateContainerRegistry-G81GcCRm.cjs +0 -1261
- package/dist/StateContainerRegistry-G81GcCRm.cjs.map +0 -1
- package/dist/StateContainerRegistry-lIwo-0m3.cjs.map +0 -1
- package/dist/acquire-B1LYXSGj.js.map +0 -1
- package/dist/acquire-B1Wuqla6.cjs.map +0 -1
- package/dist/acquire-BJ3xUEmh.cjs.map +0 -1
- package/dist/acquire-BP-ZfUH2.js.map +0 -1
- package/dist/acquire-BRIJVJaA.js.map +0 -1
- package/dist/acquire-BZIs6tpN.cjs.map +0 -1
- package/dist/acquire-B_p1fNEh.cjs.map +0 -1
- package/dist/acquire-BdsVZBSe.js.map +0 -1
- package/dist/acquire-C3nOb3XR.cjs +0 -46
- package/dist/acquire-C3nOb3XR.cjs.map +0 -1
- package/dist/acquire-C4WAS13G.cjs +0 -46
- package/dist/acquire-C4WAS13G.cjs.map +0 -1
- package/dist/acquire-C7beGI55.cjs +0 -46
- package/dist/acquire-C7beGI55.cjs.map +0 -1
- package/dist/acquire-CE0uq0Dx.cjs +0 -46
- package/dist/acquire-CE0uq0Dx.cjs.map +0 -1
- package/dist/acquire-CU0u8BMn.js +0 -35
- package/dist/acquire-CU0u8BMn.js.map +0 -1
- package/dist/acquire-CbMz7gWs.cjs +0 -46
- package/dist/acquire-CbMz7gWs.cjs.map +0 -1
- package/dist/acquire-CkgLJ8WL.cjs +0 -46
- package/dist/acquire-CkgLJ8WL.cjs.map +0 -1
- package/dist/acquire-CwB083au.js +0 -35
- package/dist/acquire-CwB083au.js.map +0 -1
- package/dist/acquire-DHEOEVcj.cjs +0 -46
- package/dist/acquire-DHEOEVcj.cjs.map +0 -1
- package/dist/acquire-DTvfYJ0y.js +0 -35
- package/dist/acquire-DTvfYJ0y.js.map +0 -1
- package/dist/acquire-DXEQDZGr.js +0 -35
- package/dist/acquire-DXEQDZGr.js.map +0 -1
- package/dist/acquire-Dg-uXwjF.js +0 -35
- package/dist/acquire-Dg-uXwjF.js.map +0 -1
- package/dist/acquire-Don7499S.js +0 -35
- package/dist/acquire-Don7499S.js.map +0 -1
- package/dist/acquire-G8aB3GAx.js +0 -35
- package/dist/acquire-G8aB3GAx.js.map +0 -1
- package/dist/branded-BybA0_xw.cjs +0 -18
- package/dist/branded-BybA0_xw.cjs.map +0 -1
- package/dist/branded-DkbUzncc.js +0 -13
- package/dist/branded-DkbUzncc.js.map +0 -1
- package/dist/config-8pyOC5gv.js +0 -16
- package/dist/config-8pyOC5gv.js.map +0 -1
- package/dist/config-B1l8ZGlU.cjs +0 -32
- package/dist/config-B1l8ZGlU.cjs.map +0 -1
- package/dist/config-C1T6Jw7n.cjs +0 -32
- package/dist/config-C1T6Jw7n.cjs.map +0 -1
- package/dist/config-C7Ktkjh2.cjs +0 -32
- package/dist/config-C7Ktkjh2.cjs.map +0 -1
- package/dist/config-COT4Xkbc.js +0 -16
- package/dist/config-COT4Xkbc.js.map +0 -1
- package/dist/config-CzcoAvBo.js +0 -16
- package/dist/config-CzcoAvBo.js.map +0 -1
- package/dist/config-D2A8ZYRM.js +0 -16
- package/dist/config-D2A8ZYRM.js.map +0 -1
- package/dist/config-D34BkraU.cjs +0 -32
- package/dist/config-D34BkraU.cjs.map +0 -1
- package/dist/config-D6BoWWPv.js +0 -16
- package/dist/config-D6BoWWPv.js.map +0 -1
- package/dist/config-DOO82lbZ.js +0 -16
- package/dist/config-DOO82lbZ.js.map +0 -1
- package/dist/config-DVM_ESQt.js +0 -16
- package/dist/config-DVM_ESQt.js.map +0 -1
- package/dist/config-DVMnlHLv.cjs +0 -32
- package/dist/config-DVMnlHLv.cjs.map +0 -1
- package/dist/config-DWUq7zEQ.cjs +0 -32
- package/dist/config-DWUq7zEQ.cjs.map +0 -1
- package/dist/config-DXI3kzmA.js +0 -16
- package/dist/config-DXI3kzmA.js.map +0 -1
- package/dist/config-Dk1FxfXj.js +0 -16
- package/dist/config-Dk1FxfXj.js.map +0 -1
- package/dist/config-ZVy_yFZ3.js +0 -16
- package/dist/config-ZVy_yFZ3.js.map +0 -1
- package/dist/config-b2z51Y_C.cjs +0 -32
- package/dist/config-b2z51Y_C.cjs.map +0 -1
- package/dist/config-buwpT7l3.js +0 -16
- package/dist/config-buwpT7l3.js.map +0 -1
- package/dist/config-cwaTn5oy.cjs +0 -32
- package/dist/config-cwaTn5oy.cjs.map +0 -1
- package/dist/config-d9_U58ef.cjs +0 -32
- package/dist/config-d9_U58ef.cjs.map +0 -1
- package/dist/config-hWTayX76.cjs +0 -32
- package/dist/config-hWTayX76.cjs.map +0 -1
- package/dist/config-sCPKPYxZ.cjs +0 -32
- package/dist/config-sCPKPYxZ.cjs.map +0 -1
- package/dist/debug.cjs +0 -14
- package/dist/debug.d.cts +0 -34
- package/dist/debug.d.ts +0 -34
- package/dist/debug.js +0 -4
- package/dist/ensure-11-asM1e.js.map +0 -1
- package/dist/ensure-B1dEDsZV.cjs +0 -559
- package/dist/ensure-B1dEDsZV.cjs.map +0 -1
- package/dist/ensure-B2DYCbbI.cjs.map +0 -1
- package/dist/ensure-B59ri8oo.js.map +0 -1
- package/dist/ensure-B9oOqpOB.cjs +0 -558
- package/dist/ensure-B9oOqpOB.cjs.map +0 -1
- package/dist/ensure-BEeY5Ab7.js.map +0 -1
- package/dist/ensure-BKdq5xsY.cjs.map +0 -1
- package/dist/ensure-BSJHkUNX.js.map +0 -1
- package/dist/ensure-BfYnvAsI.js +0 -709
- package/dist/ensure-BfYnvAsI.js.map +0 -1
- package/dist/ensure-Bm91o37h.js +0 -536
- package/dist/ensure-Bm91o37h.js.map +0 -1
- package/dist/ensure-C1a8IFWy.js +0 -535
- package/dist/ensure-C1a8IFWy.js.map +0 -1
- package/dist/ensure-CLQEx0Nn.cjs +0 -528
- package/dist/ensure-CLQEx0Nn.cjs.map +0 -1
- package/dist/ensure-CPMiGvov.js +0 -493
- package/dist/ensure-CPMiGvov.js.map +0 -1
- package/dist/ensure-CQimeD0I.cjs +0 -559
- package/dist/ensure-CQimeD0I.cjs.map +0 -1
- package/dist/ensure-D3WWWwMo.cjs.map +0 -1
- package/dist/ensure-DEXSmA-N.js +0 -526
- package/dist/ensure-DEXSmA-N.js.map +0 -1
- package/dist/ensure-DTTTd2h8.js +0 -536
- package/dist/ensure-DTTTd2h8.js.map +0 -1
- package/dist/ensure-Dx86f80B.cjs +0 -567
- package/dist/ensure-Dx86f80B.cjs.map +0 -1
- package/dist/ensure-DzqGej43.js +0 -526
- package/dist/ensure-DzqGej43.js.map +0 -1
- package/dist/ensure-VuiNPccZ.cjs +0 -559
- package/dist/ensure-VuiNPccZ.cjs.map +0 -1
- package/dist/ensure-_Oh8XPm4.cjs +0 -732
- package/dist/ensure-_Oh8XPm4.cjs.map +0 -1
- package/dist/ensure-fsQMjaQL.cjs +0 -567
- package/dist/ensure-fsQMjaQL.cjs.map +0 -1
- package/dist/ensure-r1C_7K6_.cjs.map +0 -1
- package/dist/ensure-vxAGa2v3.js +0 -536
- package/dist/ensure-vxAGa2v3.js.map +0 -1
- package/dist/events.d.cts +0 -42
- package/dist/events.d.ts +0 -42
- package/dist/management-14vsHr4t.cjs +0 -85
- package/dist/management-14vsHr4t.cjs.map +0 -1
- package/dist/management-444tdCBG.js +0 -38
- package/dist/management-444tdCBG.js.map +0 -1
- package/dist/management-7jLjVHJd.js +0 -38
- package/dist/management-7jLjVHJd.js.map +0 -1
- package/dist/management-8x1OVMi6.js +0 -38
- package/dist/management-8x1OVMi6.js.map +0 -1
- package/dist/management-AFuqQEwz.js +0 -38
- package/dist/management-AFuqQEwz.js.map +0 -1
- package/dist/management-BZgsi29F.js +0 -38
- package/dist/management-BZgsi29F.js.map +0 -1
- package/dist/management-BodVLAfJ.cjs +0 -85
- package/dist/management-BodVLAfJ.cjs.map +0 -1
- package/dist/management-BqGBdL01.js +0 -38
- package/dist/management-BqGBdL01.js.map +0 -1
- package/dist/management-BvUAjril.js +0 -38
- package/dist/management-BvUAjril.js.map +0 -1
- package/dist/management-C-WGcwPD.js +0 -38
- package/dist/management-C-WGcwPD.js.map +0 -1
- package/dist/management-C2wv4vGS.cjs +0 -85
- package/dist/management-C2wv4vGS.cjs.map +0 -1
- package/dist/management-D2pjr38g.js +0 -38
- package/dist/management-D2pjr38g.js.map +0 -1
- package/dist/management-D5WsZoTV.js +0 -38
- package/dist/management-D5WsZoTV.js.map +0 -1
- package/dist/management-DAV9sN-k.cjs +0 -85
- package/dist/management-DAV9sN-k.cjs.map +0 -1
- package/dist/management-Df7Y2sF1.cjs +0 -85
- package/dist/management-Df7Y2sF1.cjs.map +0 -1
- package/dist/management-Dg2SxUb6.cjs +0 -85
- package/dist/management-Dg2SxUb6.cjs.map +0 -1
- package/dist/management-DwO0nBzL.cjs +0 -85
- package/dist/management-DwO0nBzL.cjs.map +0 -1
- package/dist/management-GcnNJjnm.cjs +0 -85
- package/dist/management-GcnNJjnm.cjs.map +0 -1
- package/dist/management-P_Vi_cvw.js +0 -38
- package/dist/management-P_Vi_cvw.js.map +0 -1
- package/dist/management-QWLpbXlW.cjs +0 -85
- package/dist/management-QWLpbXlW.cjs.map +0 -1
- package/dist/management-hkY13log.cjs +0 -85
- package/dist/management-hkY13log.cjs.map +0 -1
- package/dist/management-iE4x6IQY.cjs +0 -85
- package/dist/management-iE4x6IQY.cjs.map +0 -1
- package/dist/types.cjs +0 -3
- package/dist/types.d.cts +0 -8
- package/dist/types.d.ts +0 -8
- package/dist/types.js +0 -2
- package/dist/watch/observe.d.ts +0 -13
- package/dist/watch-B0pUfh-v.cjs +0 -119
- package/dist/watch-B0pUfh-v.cjs.map +0 -1
- package/dist/watch-B91opmva.cjs +0 -70
- package/dist/watch-B91opmva.cjs.map +0 -1
- package/dist/watch-BDiwCPmb.js +0 -108
- package/dist/watch-BDiwCPmb.js.map +0 -1
- package/dist/watch-BHfCtbn1.cjs +0 -119
- package/dist/watch-BHfCtbn1.cjs.map +0 -1
- package/dist/watch-BW7gYiDf.js +0 -108
- package/dist/watch-BW7gYiDf.js.map +0 -1
- package/dist/watch-BmC-Tyqg.js +0 -59
- package/dist/watch-BmC-Tyqg.js.map +0 -1
- package/dist/watch-Bx0y-Kcc.js +0 -108
- package/dist/watch-Bx0y-Kcc.js.map +0 -1
- package/dist/watch-CKWt788i.cjs +0 -70
- package/dist/watch-CKWt788i.cjs.map +0 -1
- package/dist/watch-CfrSSrRY.js +0 -59
- package/dist/watch-CfrSSrRY.js.map +0 -1
- package/dist/watch-Cnh3PtQA.cjs +0 -70
- package/dist/watch-Cnh3PtQA.cjs.map +0 -1
- package/dist/watch-D01MdwKy.js +0 -108
- package/dist/watch-D01MdwKy.js.map +0 -1
- package/dist/watch-D8hwbFU1.js +0 -59
- package/dist/watch-D8hwbFU1.js.map +0 -1
- package/dist/watch-DPVUwPUY.js +0 -59
- package/dist/watch-DPVUwPUY.js.map +0 -1
- package/dist/watch-DVmvZBMD.cjs +0 -70
- package/dist/watch-DVmvZBMD.cjs.map +0 -1
- package/dist/watch-DkDGmGAx.cjs +0 -119
- package/dist/watch-DkDGmGAx.cjs.map +0 -1
- package/dist/watch-DttHqefn.js +0 -108
- package/dist/watch-DttHqefn.js.map +0 -1
- package/dist/watch-DxdIZjpt.cjs +0 -119
- package/dist/watch-DxdIZjpt.cjs.map +0 -1
- package/dist/watch-DztcJuUy.cjs +0 -119
- package/dist/watch-DztcJuUy.cjs.map +0 -1
- package/dist/watch-IrR8G28N.js +0 -108
- package/dist/watch-IrR8G28N.js.map +0 -1
- package/dist/watch-aoNLQAXp.cjs +0 -119
- package/dist/watch-aoNLQAXp.cjs.map +0 -1
- package/dist/watch-entry.cjs +0 -4
- package/dist/watch-entry.d.cts +0 -24
- package/dist/watch-entry.d.ts +0 -24
- package/dist/watch-entry.js +0 -2
- package/dist/watch-hx0r92Zc.js +0 -108
- package/dist/watch-hx0r92Zc.js.map +0 -1
- package/dist/watch-lEco5Tbl.cjs +0 -119
- package/dist/watch-lEco5Tbl.cjs.map +0 -1
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ALL_PATHS } from "@dirtytalk/structural";
|
|
2
1
|
//#region src/config.ts
|
|
3
2
|
/**
|
|
4
3
|
* Default equality: shallow per-key `Object.is` comparison.
|
|
@@ -9,13 +8,16 @@ const shallowEqualState = (prev, next) => {
|
|
|
9
8
|
if (Object.is(prev, next)) return true;
|
|
10
9
|
if (typeof prev !== "object" || prev === null) return false;
|
|
11
10
|
if (typeof next !== "object" || next === null) return false;
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
const p = prev;
|
|
12
|
+
const n = next;
|
|
13
|
+
let prevCount = 0;
|
|
14
|
+
for (const key in p) {
|
|
15
|
+
prevCount++;
|
|
16
|
+
if (!Object.is(p[key], n[key])) return false;
|
|
17
|
+
}
|
|
18
|
+
let nextCount = 0;
|
|
19
|
+
for (const _ in n) nextCount++;
|
|
20
|
+
return prevCount === nextCount;
|
|
19
21
|
};
|
|
20
22
|
const defaultConfig = {
|
|
21
23
|
equality: shallowEqualState,
|
|
@@ -25,7 +27,7 @@ const defaultConfig = {
|
|
|
25
27
|
};
|
|
26
28
|
let globalConfig = { ...defaultConfig };
|
|
27
29
|
/**
|
|
28
|
-
* Configure global defaults for
|
|
30
|
+
* Configure global defaults for `@blac/core`.
|
|
29
31
|
*
|
|
30
32
|
* @example
|
|
31
33
|
* ```ts
|
|
@@ -56,331 +58,6 @@ function resetBlacConfig() {
|
|
|
56
58
|
globalConfig = { ...defaultConfig };
|
|
57
59
|
}
|
|
58
60
|
//#endregion
|
|
59
|
-
//#region src/plugin/PluginManager.ts
|
|
60
|
-
/**
|
|
61
|
-
* Manages plugin lifecycle for the BlaC state management system.
|
|
62
|
-
*
|
|
63
|
-
* The manager hooks into two surfaces:
|
|
64
|
-
*
|
|
65
|
-
* 1. **Registry lifecycle events** (`created`, `disposed`, `refAcquired`,
|
|
66
|
-
* `refReleased`, `depsChanged`) — synchronous, fired by the registry.
|
|
67
|
-
*
|
|
68
|
-
* 2. **Per-container channel flushes** — microtask-coalesced. For each
|
|
69
|
-
* container, the manager subscribes once at create-time with
|
|
70
|
-
* `ALL_PATHS` interest and stashes `prevState`. On every flush it
|
|
71
|
-
* captures the new state + the changed `PathSet` and dispatches
|
|
72
|
-
* `onStateChange(ctx, prev, next, paths)` to every enabled plugin.
|
|
73
|
-
*
|
|
74
|
-
* The `ALL_PATHS` subscription cost: plugins counted as a consumer with
|
|
75
|
-
* `ALL_PATHS` interest will defeat the single-consumer-skip optimization
|
|
76
|
-
* in `StructuralContainer`. This is the intended trade-off — devtools /
|
|
77
|
-
* persist plugins genuinely want every change, and stateful plugins
|
|
78
|
-
* (logging) can decode `paths` via `container.interner.lookup(id)` to log
|
|
79
|
-
* only relevant fields. Plugins that want low overhead should remain
|
|
80
|
-
* uninstalled or environment-gated.
|
|
81
|
-
*
|
|
82
|
-
* @example
|
|
83
|
-
* ```ts
|
|
84
|
-
* const manager = createPluginManager(registry);
|
|
85
|
-
* manager.install(myPlugin, { environment: 'development' });
|
|
86
|
-
* ```
|
|
87
|
-
*/
|
|
88
|
-
var PluginManager = class {
|
|
89
|
-
/**
|
|
90
|
-
* Create a new PluginManager
|
|
91
|
-
* @param registry - The StateContainerRegistry to monitor for lifecycle events
|
|
92
|
-
*/
|
|
93
|
-
constructor(registry) {
|
|
94
|
-
this.plugins = /* @__PURE__ */ new Map();
|
|
95
|
-
this.lifecycleUnsubscribers = [];
|
|
96
|
-
this.containerBridges = /* @__PURE__ */ new WeakMap();
|
|
97
|
-
this.registry = registry;
|
|
98
|
-
this.setupLifecycleHooks();
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Install a plugin with optional configuration
|
|
102
|
-
* @param plugin - The plugin to install
|
|
103
|
-
* @param config - Optional plugin configuration
|
|
104
|
-
* @throws Error if plugin is already installed
|
|
105
|
-
*/
|
|
106
|
-
install(plugin, config = {}) {
|
|
107
|
-
const effectiveConfig = {
|
|
108
|
-
enabled: true,
|
|
109
|
-
environment: "all",
|
|
110
|
-
...config
|
|
111
|
-
};
|
|
112
|
-
if (!this.shouldEnablePlugin(effectiveConfig)) {
|
|
113
|
-
console.log(`[BlaC] Plugin "${plugin.name}" skipped (environment mismatch)`);
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
if (this.plugins.has(plugin.name)) throw new Error(`Plugin "${plugin.name}" is already installed`);
|
|
117
|
-
const installContext = this.buildContext(void 0);
|
|
118
|
-
this.plugins.set(plugin.name, {
|
|
119
|
-
plugin,
|
|
120
|
-
config: effectiveConfig,
|
|
121
|
-
installContext
|
|
122
|
-
});
|
|
123
|
-
if (plugin.onInstall) try {
|
|
124
|
-
plugin.onInstall(installContext);
|
|
125
|
-
} catch (error) {
|
|
126
|
-
console.error(`[BlaC] Error installing plugin "${plugin.name}":`, error);
|
|
127
|
-
this.plugins.delete(plugin.name);
|
|
128
|
-
throw error;
|
|
129
|
-
}
|
|
130
|
-
console.log(`[BlaC] Plugin "${plugin.name}" v${plugin.version} installed`);
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Uninstall a plugin by name
|
|
134
|
-
* @param pluginName - The name of the plugin to uninstall
|
|
135
|
-
* @throws Error if plugin is not installed
|
|
136
|
-
*/
|
|
137
|
-
uninstall(pluginName) {
|
|
138
|
-
const installed = this.plugins.get(pluginName);
|
|
139
|
-
if (!installed) throw new Error(`Plugin "${pluginName}" is not installed`);
|
|
140
|
-
if (installed.plugin.onUninstall) try {
|
|
141
|
-
installed.plugin.onUninstall();
|
|
142
|
-
} catch (error) {
|
|
143
|
-
console.error(`[BlaC] Error uninstalling plugin "${pluginName}":`, error);
|
|
144
|
-
}
|
|
145
|
-
this.plugins.delete(pluginName);
|
|
146
|
-
console.log(`[BlaC] Plugin "${pluginName}" uninstalled`);
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Get an installed plugin by name
|
|
150
|
-
* @param pluginName - The name of the plugin to retrieve
|
|
151
|
-
* @returns The plugin instance or undefined if not found
|
|
152
|
-
*/
|
|
153
|
-
getPlugin(pluginName) {
|
|
154
|
-
return this.plugins.get(pluginName)?.plugin;
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Get all installed plugins
|
|
158
|
-
* @returns Array of all installed plugins
|
|
159
|
-
*/
|
|
160
|
-
getAllPlugins() {
|
|
161
|
-
return Array.from(this.plugins.values()).map((p) => p.plugin);
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Check if a plugin is installed
|
|
165
|
-
* @param pluginName - The name of the plugin to check
|
|
166
|
-
* @returns true if the plugin is installed
|
|
167
|
-
*/
|
|
168
|
-
hasPlugin(pluginName) {
|
|
169
|
-
return this.plugins.has(pluginName);
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Uninstall all plugins
|
|
173
|
-
*/
|
|
174
|
-
clear() {
|
|
175
|
-
for (const name of this.plugins.keys()) this.uninstall(name);
|
|
176
|
-
}
|
|
177
|
-
destroy() {
|
|
178
|
-
this.clear();
|
|
179
|
-
for (const unsub of this.lifecycleUnsubscribers) unsub();
|
|
180
|
-
this.lifecycleUnsubscribers = [];
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Wire registry lifecycle events into plugin dispatch.
|
|
184
|
-
*
|
|
185
|
-
* `onStateChange` is NOT wired through `registry.on('stateChanged', …)` —
|
|
186
|
-
* that event lacks the `PathSet` payload. Instead, on each `created` we
|
|
187
|
-
* subscribe to the container's channel directly so we get
|
|
188
|
-
* `(paths)` and capture `(prev, next)` via the per-container snapshot.
|
|
189
|
-
*/
|
|
190
|
-
setupLifecycleHooks() {
|
|
191
|
-
this.lifecycleUnsubscribers = [
|
|
192
|
-
this.registry.on("created", (instance) => {
|
|
193
|
-
this.attachStateBridge(instance);
|
|
194
|
-
this.notifyPlugins("onCreated", instance);
|
|
195
|
-
}),
|
|
196
|
-
this.registry.on("disposed", (instance) => {
|
|
197
|
-
this.notifyPlugins("onDestroyed", instance);
|
|
198
|
-
this.detachStateBridge(instance);
|
|
199
|
-
}),
|
|
200
|
-
this.registry.on("refAcquired", (instance, refId) => {
|
|
201
|
-
this.notifyPlugins("onRefAcquired", instance, refId);
|
|
202
|
-
}),
|
|
203
|
-
this.registry.on("refReleased", (instance, refId) => {
|
|
204
|
-
this.notifyPlugins("onRefReleased", instance, refId);
|
|
205
|
-
}),
|
|
206
|
-
this.registry.on("depsChanged", (instance, previousDeps, currentDeps) => {
|
|
207
|
-
this.notifyPlugins("onDepsChanged", instance, previousDeps, currentDeps);
|
|
208
|
-
}),
|
|
209
|
-
this.registry.on("hydrationChanged", (instance, status, previousStatus) => {
|
|
210
|
-
this.notifyPlugins("onHydrationChange", instance, status, previousStatus);
|
|
211
|
-
})
|
|
212
|
-
];
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* Subscribe to the container's channel with `ALL_PATHS` interest, so we
|
|
216
|
-
* fire on every flush. Capture `prev` from the snapshot taken on the
|
|
217
|
-
* previous flush (or at create-time for the first flush) and pass the
|
|
218
|
-
* channel's `paths` argument straight through to plugins.
|
|
219
|
-
*
|
|
220
|
-
* Per-container bookkeeping is stored in a `WeakMap` keyed by the
|
|
221
|
-
* container itself, so a disposed/GC'd container drops cleanly.
|
|
222
|
-
*/
|
|
223
|
-
attachStateBridge(container) {
|
|
224
|
-
if (this.containerBridges.has(container)) return;
|
|
225
|
-
const bridge = {
|
|
226
|
-
unsub: () => {},
|
|
227
|
-
prevState: container.state
|
|
228
|
-
};
|
|
229
|
-
this.containerBridges.set(container, bridge);
|
|
230
|
-
bridge.unsub = container.channel.subscribe(() => ALL_PATHS, (paths) => this.dispatchStateChange(container, paths));
|
|
231
|
-
}
|
|
232
|
-
detachStateBridge(container) {
|
|
233
|
-
const bridge = this.containerBridges.get(container);
|
|
234
|
-
if (!bridge) return;
|
|
235
|
-
bridge.unsub();
|
|
236
|
-
this.containerBridges.delete(container);
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Channel-flush callback. Snapshots `next`, hands `(prev, next, paths)`
|
|
240
|
-
* to every enabled plugin's `onStateChange`, then updates `prevState`
|
|
241
|
-
* for the next flush.
|
|
242
|
-
*
|
|
243
|
-
* Note: `prev` is captured once and reused across plugins — every
|
|
244
|
-
* plugin sees the same `prev`/`next`/`paths` regardless of dispatch
|
|
245
|
-
* order, matching the "snapshot prev once per flush" invariant.
|
|
246
|
-
*/
|
|
247
|
-
dispatchStateChange(container, paths) {
|
|
248
|
-
const bridge = this.containerBridges.get(container);
|
|
249
|
-
if (!bridge) return;
|
|
250
|
-
const prev = bridge.prevState;
|
|
251
|
-
const next = container.state;
|
|
252
|
-
bridge.prevState = next;
|
|
253
|
-
let ctx;
|
|
254
|
-
for (const { plugin, config } of this.plugins.values()) {
|
|
255
|
-
if (!config.enabled) continue;
|
|
256
|
-
const hook = plugin.onStateChange;
|
|
257
|
-
if (typeof hook !== "function") continue;
|
|
258
|
-
try {
|
|
259
|
-
ctx ??= this.buildContext(container);
|
|
260
|
-
hook.call(plugin, ctx, prev, next, paths);
|
|
261
|
-
} catch (error) {
|
|
262
|
-
console.error(`[BlaC] Error in plugin "${plugin.name}" onStateChange:`, error);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Notify all plugins of a lifecycle event.
|
|
268
|
-
*
|
|
269
|
-
* Builds a fresh `PluginContext` per dispatch (instance becomes
|
|
270
|
-
* `ctx.container`), so plugins can reach the focal bloc through
|
|
271
|
-
* `ctx.container`. The context is built lazily on the first matching
|
|
272
|
-
* hook and reused for every other plugin in this dispatch — zero
|
|
273
|
-
* builds if no enabled plugin implements `hookName`.
|
|
274
|
-
*/
|
|
275
|
-
notifyPlugins(hookName, instance, ...extraArgs) {
|
|
276
|
-
let ctx;
|
|
277
|
-
for (const { plugin, config } of this.plugins.values()) {
|
|
278
|
-
if (!config.enabled) continue;
|
|
279
|
-
const hook = plugin[hookName];
|
|
280
|
-
if (typeof hook !== "function") continue;
|
|
281
|
-
try {
|
|
282
|
-
ctx ??= this.buildContext(instance);
|
|
283
|
-
hook.call(plugin, ctx, ...extraArgs);
|
|
284
|
-
} catch (error) {
|
|
285
|
-
console.error(`[BlaC] Error in plugin "${plugin.name}" ${hookName}:`, error);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* Build a `PluginContext` for a given focal container. The context is
|
|
291
|
-
* cheap to build — its methods close over `this.registry` directly —
|
|
292
|
-
* so we create one per dispatch rather than caching per container.
|
|
293
|
-
* This sidesteps the lifetime question of "when do we evict a cached
|
|
294
|
-
* context?" and keeps `paths`-vs-`container` lifetimes cleanly
|
|
295
|
-
* separated.
|
|
296
|
-
*/
|
|
297
|
-
buildContext(container) {
|
|
298
|
-
const registry = this.registry;
|
|
299
|
-
return {
|
|
300
|
-
container,
|
|
301
|
-
getInstanceMetadata: (instance) => {
|
|
302
|
-
return {
|
|
303
|
-
id: instance.$blac.id,
|
|
304
|
-
className: instance.constructor.name,
|
|
305
|
-
isDisposed: instance.$blac.disposed,
|
|
306
|
-
name: instance.$blac.name,
|
|
307
|
-
createdAt: instance.$blac.createdAt,
|
|
308
|
-
state: instance.state,
|
|
309
|
-
hydrationStatus: instance.$blac.hydration.status,
|
|
310
|
-
isHydrated: instance.$blac.hydration.isHydrated,
|
|
311
|
-
hydrationError: instance.$blac.hydration.error,
|
|
312
|
-
changedWhileHydrating: instance.$blac.hydration.changedWhileHydrating,
|
|
313
|
-
args: instance.args
|
|
314
|
-
};
|
|
315
|
-
},
|
|
316
|
-
getState: (instance) => {
|
|
317
|
-
return instance.state;
|
|
318
|
-
},
|
|
319
|
-
getHydrationStatus: (instance) => {
|
|
320
|
-
return instance.$blac.hydration.status;
|
|
321
|
-
},
|
|
322
|
-
startHydration: (instance) => {
|
|
323
|
-
instance.$blac.hydration.begin();
|
|
324
|
-
},
|
|
325
|
-
applyHydratedState: (instance, state) => {
|
|
326
|
-
return instance.$blac.hydration.apply(state);
|
|
327
|
-
},
|
|
328
|
-
finishHydration: (instance) => {
|
|
329
|
-
instance.$blac.hydration.finish();
|
|
330
|
-
},
|
|
331
|
-
failHydration: (instance, error) => {
|
|
332
|
-
instance.$blac.hydration.fail(error);
|
|
333
|
-
},
|
|
334
|
-
waitForHydration: (instance) => {
|
|
335
|
-
return instance.$blac.hydration.wait();
|
|
336
|
-
},
|
|
337
|
-
queryInstances: (typeClass) => {
|
|
338
|
-
return registry.getAll(typeClass);
|
|
339
|
-
},
|
|
340
|
-
getAllTypes: () => {
|
|
341
|
-
return registry.getTypes();
|
|
342
|
-
},
|
|
343
|
-
getStats: () => {
|
|
344
|
-
return registry.getStats();
|
|
345
|
-
},
|
|
346
|
-
getRefIds: (instanceId) => {
|
|
347
|
-
for (const Type of registry.getTypes()) {
|
|
348
|
-
const map = registry.getInstancesMap(Type);
|
|
349
|
-
for (const [, entry] of map) if (entry.instance.$blac.id === instanceId) return Array.from(entry.refs.keys());
|
|
350
|
-
}
|
|
351
|
-
return [];
|
|
352
|
-
}
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Check if plugin should be enabled based on environment
|
|
357
|
-
*/
|
|
358
|
-
shouldEnablePlugin(config) {
|
|
359
|
-
if (!config.enabled) return false;
|
|
360
|
-
if (config.environment === "all") return true;
|
|
361
|
-
return this.getCurrentEnvironment() === config.environment;
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Get current environment
|
|
365
|
-
*/
|
|
366
|
-
getCurrentEnvironment() {
|
|
367
|
-
if (typeof process !== "undefined") {
|
|
368
|
-
if (process.env.NODE_ENV === "test") return "test";
|
|
369
|
-
if (process.env.NODE_ENV === "production") return "production";
|
|
370
|
-
return "development";
|
|
371
|
-
}
|
|
372
|
-
return "development";
|
|
373
|
-
}
|
|
374
|
-
};
|
|
375
|
-
/**
|
|
376
|
-
* Create a plugin manager instance
|
|
377
|
-
* @param registry - The StateContainerRegistry to monitor for lifecycle events
|
|
378
|
-
* @returns A new PluginManager instance
|
|
379
|
-
*/
|
|
380
|
-
function createPluginManager(registry) {
|
|
381
|
-
return new PluginManager(registry);
|
|
382
|
-
}
|
|
383
|
-
//#endregion
|
|
384
61
|
//#region src/constants.ts
|
|
385
62
|
/**
|
|
386
63
|
* Default configuration constants for BlaC
|
|
@@ -388,19 +65,6 @@ function createPluginManager(registry) {
|
|
|
388
65
|
* Centralized location for all magic numbers and default values.
|
|
389
66
|
*/
|
|
390
67
|
/**
|
|
391
|
-
* Default configuration constants for BlaC
|
|
392
|
-
*/
|
|
393
|
-
const BLAC_DEFAULTS = {
|
|
394
|
-
/**
|
|
395
|
-
* Default instance key for shared instances
|
|
396
|
-
*/
|
|
397
|
-
DEFAULT_INSTANCE_KEY: "default",
|
|
398
|
-
/**
|
|
399
|
-
* Maximum getter nesting depth (prevents infinite recursion)
|
|
400
|
-
*/
|
|
401
|
-
MAX_GETTER_DEPTH: 10
|
|
402
|
-
};
|
|
403
|
-
/**
|
|
404
68
|
* Static property names for StateContainer classes
|
|
405
69
|
* Used for feature flags and configuration on bloc classes
|
|
406
70
|
*/
|
|
@@ -425,19 +89,42 @@ const BLAC_STATIC_PROPS = {
|
|
|
425
89
|
* instead of using a structural hash of `args`. Allows blocs to ignore
|
|
426
90
|
* non-identity fields (e.g., `readonly` flags) while still keying by id.
|
|
427
91
|
*/
|
|
428
|
-
KEY: "key"
|
|
92
|
+
KEY: "key",
|
|
93
|
+
/**
|
|
94
|
+
* Explicit, minification-safe identity for a bloc class: `static blacName = '...'`.
|
|
95
|
+
* When unset, identity falls back to `constructor.name`.
|
|
96
|
+
*/
|
|
97
|
+
BLAC_NAME: "blacName"
|
|
429
98
|
};
|
|
430
99
|
/**
|
|
431
100
|
* Standard error message prefix
|
|
432
101
|
*/
|
|
433
102
|
const BLAC_ERROR_PREFIX = "[BlaC]";
|
|
103
|
+
/**
|
|
104
|
+
* True only when `process.env.NODE_ENV` is defined and not `'production'`.
|
|
105
|
+
*
|
|
106
|
+
* Dev-only checks (emit-rate breaker, deps collision scan, args-mismatch key)
|
|
107
|
+
* cost real work per emit/acquire, so an environment that says nothing about
|
|
108
|
+
* its mode — plain ESM in the browser, Deno, a bundle without a `process`
|
|
109
|
+
* shim — is treated as production. Bundlers that define `process.env.NODE_ENV`
|
|
110
|
+
* still constant-fold the read.
|
|
111
|
+
*/
|
|
112
|
+
const nodeEnv = (() => {
|
|
113
|
+
try {
|
|
114
|
+
return process.env.NODE_ENV;
|
|
115
|
+
} catch {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
})();
|
|
119
|
+
const IS_DEV = nodeEnv !== void 0 && nodeEnv !== "production";
|
|
434
120
|
//#endregion
|
|
435
121
|
//#region src/utils/static-props.ts
|
|
436
122
|
/**
|
|
437
123
|
* Utility functions for accessing static properties on StateContainer classes
|
|
438
124
|
*/
|
|
439
125
|
/**
|
|
440
|
-
* Get a static property from a class constructor
|
|
126
|
+
* Get a static property from a class constructor, walking the prototype
|
|
127
|
+
* chain so subclasses inherit the value unless they define their own.
|
|
441
128
|
* Type-safe helper that avoids (Type as any) casts
|
|
442
129
|
*
|
|
443
130
|
* @param Type - The class constructor
|
|
@@ -449,8 +136,20 @@ function getStaticProp(Type, propName, defaultValue) {
|
|
|
449
136
|
return Type[propName] ?? defaultValue;
|
|
450
137
|
}
|
|
451
138
|
/**
|
|
139
|
+
* Get a static property declared directly on `Type`, ignoring the prototype
|
|
140
|
+
* chain, so subclasses never inherit a base class's value.
|
|
141
|
+
*
|
|
142
|
+
* @param Type - The class constructor
|
|
143
|
+
* @param propName - The property name to access
|
|
144
|
+
* @returns The own property value or `undefined`
|
|
145
|
+
*/
|
|
146
|
+
function getOwnStaticProp(Type, propName) {
|
|
147
|
+
return Object.hasOwn(Type, propName) ? Type[propName] : void 0;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
452
150
|
* Check if a class is marked as keepAlive.
|
|
453
151
|
* KeepAlive classes are never auto-disposed when ref count reaches 0.
|
|
152
|
+
* Inherited: a subclass keeps a base class's `keepAlive` unless overridden.
|
|
454
153
|
* @param Type - The class constructor to check
|
|
455
154
|
* @returns true if the class has `static keepAlive = true`
|
|
456
155
|
*/
|
|
@@ -460,6 +159,7 @@ function isKeepAliveClass(Type) {
|
|
|
460
159
|
/**
|
|
461
160
|
* Check if a class should be excluded from DevTools.
|
|
462
161
|
* Used to prevent infinite loops when DevTools tracks itself.
|
|
162
|
+
* Inherited: a subclass keeps a base class's exclusion unless overridden.
|
|
463
163
|
* @param Type - The class constructor to check
|
|
464
164
|
* @returns true if the class has `static __excludeFromDevTools = true`
|
|
465
165
|
*/
|
|
@@ -468,6 +168,7 @@ function isExcludedFromDevTools(Type) {
|
|
|
468
168
|
}
|
|
469
169
|
/**
|
|
470
170
|
* Get the per-class equality function set via `@blac({ equality })`, if any.
|
|
171
|
+
* Inherited: a subclass keeps a base class's equality fn unless overridden.
|
|
471
172
|
* @param Type - The class constructor to check
|
|
472
173
|
* @returns the equality function or `undefined`
|
|
473
174
|
*/
|
|
@@ -476,13 +177,26 @@ function getClassEquality(Type) {
|
|
|
476
177
|
return typeof fn === "function" ? fn : void 0;
|
|
477
178
|
}
|
|
478
179
|
/**
|
|
180
|
+
* Get a class's minification-safe identity name.
|
|
181
|
+
* Own only: a subclass never inherits a base class's explicit `blacName`,
|
|
182
|
+
* since that would collapse two distinct blocs onto one identity.
|
|
183
|
+
* Falls back to `Type.name` (the runtime `constructor.name`) when unset.
|
|
184
|
+
* @param Type - The class constructor to check
|
|
185
|
+
* @returns the explicit `static blacName` or `Type.name`
|
|
186
|
+
*/
|
|
187
|
+
function getBlacName(Type) {
|
|
188
|
+
return getOwnStaticProp(Type, BLAC_STATIC_PROPS.BLAC_NAME) ?? Type.name;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
479
191
|
* Get the per-class key function set via `@blac({ key })` or `static key = …`, if any.
|
|
480
192
|
* Used by the registry to derive a stable instance key from `args`.
|
|
193
|
+
* Own only: a subclass never inherits a base class's `key`, since a
|
|
194
|
+
* different `Args` shape would derive the wrong instance key.
|
|
481
195
|
* @param Type - The class constructor to check
|
|
482
196
|
* @returns the key function or `undefined`
|
|
483
197
|
*/
|
|
484
198
|
function getClassKey(Type) {
|
|
485
|
-
const fn =
|
|
199
|
+
const fn = getOwnStaticProp(Type, BLAC_STATIC_PROPS.KEY);
|
|
486
200
|
return typeof fn === "function" ? fn : void 0;
|
|
487
201
|
}
|
|
488
202
|
//#endregion
|
|
@@ -499,11 +213,24 @@ const DEFAULT_STRUCTURAL_KEY = "default";
|
|
|
499
213
|
* - Object keys are sorted for order-independence.
|
|
500
214
|
* - Arrays keep their insertion order.
|
|
501
215
|
* - Functions throw — they must be passed via `deps`, not `args`.
|
|
216
|
+
* - Object args are memoized by identity; callers on hot paths (`resolveKey`,
|
|
217
|
+
* `depend`) re-resolve the same args object on every call.
|
|
502
218
|
*/
|
|
219
|
+
const keyCache = /* @__PURE__ */ new WeakMap();
|
|
503
220
|
function structuralKey(args) {
|
|
504
221
|
if (args === void 0 || args === null) return DEFAULT_STRUCTURAL_KEY;
|
|
222
|
+
if (typeof args === "object") {
|
|
223
|
+
const cached = keyCache.get(args);
|
|
224
|
+
if (cached !== void 0) return cached;
|
|
225
|
+
const key = serialize(args);
|
|
226
|
+
keyCache.set(args, key);
|
|
227
|
+
return key;
|
|
228
|
+
}
|
|
229
|
+
return serialize(args);
|
|
230
|
+
}
|
|
231
|
+
function serialize(args) {
|
|
505
232
|
return JSON.stringify(args, function(_k, v) {
|
|
506
|
-
if (typeof v === "function") throw new Error(
|
|
233
|
+
if (typeof v === "function") throw new Error(`[blac] args must be serializable; put refs/callbacks in \`deps\` (found a function at key "${_k || "(root)"}")`);
|
|
507
234
|
if (v && typeof v === "object" && !Array.isArray(v)) return Object.keys(v).sort().reduce((o, k) => {
|
|
508
235
|
o[k] = v[k];
|
|
509
236
|
return o;
|
|
@@ -515,7 +242,7 @@ function structuralKey(args) {
|
|
|
515
242
|
//#region src/core/symbols.ts
|
|
516
243
|
/**
|
|
517
244
|
* @internal Apply one owner's (consumer's) deps slice to an instance.
|
|
518
|
-
* Called by framework adapters (e.g.
|
|
245
|
+
* Called by framework adapters (e.g. `@blac/react` useBloc) — not public API.
|
|
519
246
|
*/
|
|
520
247
|
const APPLY_DEPS = Symbol("blac.applyDeps");
|
|
521
248
|
/**
|
|
@@ -524,6 +251,12 @@ const APPLY_DEPS = Symbol("blac.applyDeps");
|
|
|
524
251
|
*/
|
|
525
252
|
const REMOVE_DEPS_OWNER = Symbol("blac.removeDepsOwner");
|
|
526
253
|
/**
|
|
254
|
+
* @internal Subscribe to this specific instance's own disposal, bypassing
|
|
255
|
+
* the global registry `'disposed'` event. Called by `watch()` — not public
|
|
256
|
+
* API.
|
|
257
|
+
*/
|
|
258
|
+
const ON_DISPOSE = Symbol("blac.onDispose");
|
|
259
|
+
/**
|
|
527
260
|
* @internal Symbol-keyed configuration entry point on `StateContainer`.
|
|
528
261
|
* Writes the instance's identity fields (`_name`/`_debug`/`_instanceId`),
|
|
529
262
|
* resolves per-class equality, emits the registry `created` event, and runs
|
|
@@ -533,8 +266,27 @@ const REMOVE_DEPS_OWNER = Symbol("blac.removeDepsOwner");
|
|
|
533
266
|
* helpers are the sole callers, mirroring the `APPLY_DEPS` precedent.
|
|
534
267
|
*/
|
|
535
268
|
const INIT_CONFIG = Symbol("blac.initConfig");
|
|
269
|
+
/**
|
|
270
|
+
* @internal Run `fn` with `state` temporarily reporting a render's tracking
|
|
271
|
+
* proxy, so getters record the paths they read. Called by `@blac/react`'s
|
|
272
|
+
* `buildTrackedProxy` — not public API.
|
|
273
|
+
*
|
|
274
|
+
* Replaces the old `this`-Proxy receiver: getters now run with `this` bound to
|
|
275
|
+
* the real instance, so ES `#private` works in user blocs.
|
|
276
|
+
*/
|
|
277
|
+
const WITH_TRACKED_STATE = Symbol("blac.withTrackedState");
|
|
278
|
+
/**
|
|
279
|
+
* @internal Drive the activation lifecycle from the registry's 0↔1 ownership
|
|
280
|
+
* transition. Owns the per-instance AbortController so `onActivate`'s signal
|
|
281
|
+
* aborts on the matching deactivation and on dispose.
|
|
282
|
+
*
|
|
283
|
+
* Framework-only — `StateContainerRegistry` is the sole caller.
|
|
284
|
+
*/
|
|
285
|
+
const SET_ACTIVE = Symbol("blac.setActive");
|
|
536
286
|
//#endregion
|
|
537
287
|
//#region src/core/StateContainerRegistry.ts
|
|
288
|
+
/** Shared, read-only Map returned by `getInstancesMap` for unregistered types. */
|
|
289
|
+
const EMPTY_INSTANCES_MAP = /* @__PURE__ */ new Map();
|
|
538
290
|
/**
|
|
539
291
|
* Central registry for managing StateContainer instances.
|
|
540
292
|
* Handles instance lifecycle, named ref tracking, and lifecycle event emission.
|
|
@@ -548,19 +300,117 @@ const INIT_CONFIG = Symbol("blac.initConfig");
|
|
|
548
300
|
* console.log('State changed:', prev, '->', next);
|
|
549
301
|
* });
|
|
550
302
|
* ```
|
|
303
|
+
*
|
|
304
|
+
* `stateChanged` fires once per emit (microtask-deferred but uncoalesced), so
|
|
305
|
+
* listeners see every intermediate transition. Plugins' `onStateChange` fires
|
|
306
|
+
* once per channel flush with coalesced `prev`/`next` and a `PathSet`. Pick
|
|
307
|
+
* the transition log for devtools/time-travel, the plugin hook for
|
|
308
|
+
* change-driven work.
|
|
551
309
|
*/
|
|
552
310
|
var StateContainerRegistry = class {
|
|
311
|
+
/**
|
|
312
|
+
* Derived from the listener Set, never a parallel counter: `on()` with the
|
|
313
|
+
* same function twice adds once, so a counter cannot stay in step.
|
|
314
|
+
*/
|
|
315
|
+
get hasStateChangedListeners() {
|
|
316
|
+
return (this.listeners.get("stateChanged")?.size ?? 0) > 0;
|
|
317
|
+
}
|
|
553
318
|
constructor() {
|
|
554
319
|
this.instancesByConstructor = /* @__PURE__ */ new WeakMap();
|
|
555
320
|
this.types = /* @__PURE__ */ new Set();
|
|
556
|
-
this.
|
|
321
|
+
this._dependentEdges = /* @__PURE__ */ new WeakMap();
|
|
322
|
+
this._entryById = /* @__PURE__ */ new Map();
|
|
557
323
|
this.listeners = /* @__PURE__ */ new Map();
|
|
558
|
-
this._stateChangedListenerCount = 0;
|
|
559
324
|
this._pendingStateChanges = null;
|
|
560
325
|
this._autoRefIdCounter = 0;
|
|
326
|
+
this.on("disposed", (container) => this._handleDisposed(container));
|
|
561
327
|
}
|
|
562
|
-
|
|
563
|
-
|
|
328
|
+
/**
|
|
329
|
+
* Registry-internal reaction to any instance's `disposed` lifecycle event.
|
|
330
|
+
* If the disposing container is itself tracked in this registry (i.e. it
|
|
331
|
+
* was `acquire()`/`ensure()`'d, not a bare `new`), prune its Map entry and
|
|
332
|
+
* release its dependent edges on whatever it `depend()`'d on.
|
|
333
|
+
*/
|
|
334
|
+
_handleDisposed(container) {
|
|
335
|
+
const Type = container.constructor;
|
|
336
|
+
if (!this._pruneEntry(Type, container)) return;
|
|
337
|
+
const edges = this._dependentEdges.get(container);
|
|
338
|
+
if (!edges) return;
|
|
339
|
+
this._dependentEdges.delete(container);
|
|
340
|
+
for (const [DepType, keys] of edges) for (const depKey of keys) this._releaseDependent(DepType, depKey, container);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* An entry may be disposed only when nothing owns it: no public refs, no
|
|
344
|
+
* `depend()` dependents, and not keepAlive. Every dispose decision goes
|
|
345
|
+
* through here so `release()` and `_releaseDependent` cannot disagree.
|
|
346
|
+
*/
|
|
347
|
+
_isUnowned(Type, entry) {
|
|
348
|
+
return this._hasNoOwners(entry) && !isKeepAliveClass(Type);
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Pure ownership: refs plus `depend()` dependents, with no keepAlive term.
|
|
352
|
+
* `_isUnowned` is "may be disposed"; this is "nothing is using it", which is
|
|
353
|
+
* what the activation lifecycle keys off — a keepAlive instance still
|
|
354
|
+
* deactivates when its last owner goes.
|
|
355
|
+
*/
|
|
356
|
+
_hasNoOwners(entry) {
|
|
357
|
+
return entry.refs.size === 0 && (entry.dependents === void 0 || entry.dependents.size === 0);
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Single funnel for the 0↔1 ownership transition. `SET_ACTIVE` is idempotent,
|
|
361
|
+
* so every acquire/release path can call this unconditionally rather than
|
|
362
|
+
* each computing the edge itself. Emits `activated`/`deactivated` for
|
|
363
|
+
* plugins to observe the same transition `onActivate`/`onDeactivate` expose
|
|
364
|
+
* to bloc authors — after `SET_ACTIVE` has already run the instance's own
|
|
365
|
+
* hook, so plugins always see a container that has finished reacting.
|
|
366
|
+
*/
|
|
367
|
+
_syncActivation(entry) {
|
|
368
|
+
const transition = entry.instance[SET_ACTIVE](!this._hasNoOwners(entry));
|
|
369
|
+
if (transition === "none") return;
|
|
370
|
+
if (transition === "deactivated") this.emit("deactivated", entry.instance);
|
|
371
|
+
else this.emit("activated", entry.instance, transition.signal);
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Record that `dependent` resolved `Type` at `key`, so the edge can be
|
|
375
|
+
* released on the owner's disposal. Keyed per resolved key, not per type:
|
|
376
|
+
* one `depend()` handle resolves a distinct key for every `args` it is
|
|
377
|
+
* called with, and all of them must be swept.
|
|
378
|
+
*/
|
|
379
|
+
_recordDependentEdge(dependent, Type, key) {
|
|
380
|
+
let byType = this._dependentEdges.get(dependent);
|
|
381
|
+
if (!byType) this._dependentEdges.set(dependent, byType = /* @__PURE__ */ new Map());
|
|
382
|
+
let keys = byType.get(Type);
|
|
383
|
+
if (!keys) byType.set(Type, keys = /* @__PURE__ */ new Set());
|
|
384
|
+
keys.add(key);
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Remove the Map entry for `container`, if this registry is tracking it.
|
|
388
|
+
* @returns true if an entry was found and removed
|
|
389
|
+
*/
|
|
390
|
+
_pruneEntry(Type, container) {
|
|
391
|
+
const id = container._instanceId;
|
|
392
|
+
if (id === void 0) return false;
|
|
393
|
+
const entry = this._entryById.get(id);
|
|
394
|
+
if (entry === void 0 || entry.instance !== container) return false;
|
|
395
|
+
this.instancesByConstructor.get(Type)?.delete(entry.key);
|
|
396
|
+
this._entryById.delete(id);
|
|
397
|
+
return true;
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Drop `dependent`'s edge on the `Type`/`key` entry (a `depend()`-resolved
|
|
401
|
+
* instance). When that leaves the entry with no dependents AND no public
|
|
402
|
+
* refs AND it isn't keepAlive, dispose it — this recurses into the same
|
|
403
|
+
* `disposed` listener, so dep-of-dep chains unwind naturally.
|
|
404
|
+
*/
|
|
405
|
+
_releaseDependent(Type, key, dependent) {
|
|
406
|
+
const entry = this.instancesByConstructor.get(Type)?.get(key);
|
|
407
|
+
if (!entry) return;
|
|
408
|
+
entry.dependents?.delete(dependent);
|
|
409
|
+
if (this._isUnowned(Type, entry)) {
|
|
410
|
+
if (!entry.instance.$blac.disposed) entry.instance.dispose();
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
this._syncActivation(entry);
|
|
564
414
|
}
|
|
565
415
|
/**
|
|
566
416
|
* Register a type for lifecycle event tracking
|
|
@@ -575,9 +425,7 @@ var StateContainerRegistry = class {
|
|
|
575
425
|
* @throws Error if type is already registered
|
|
576
426
|
*/
|
|
577
427
|
register(constructor) {
|
|
578
|
-
|
|
579
|
-
if (this.registeredTypeNames.has(className)) throw new Error(`${BLAC_ERROR_PREFIX} Type "${className}" is already registered`);
|
|
580
|
-
this.registeredTypeNames.add(className);
|
|
428
|
+
if (this.types.has(constructor)) throw new Error(`${BLAC_ERROR_PREFIX} Type "${getBlacName(constructor)}" is already registered`);
|
|
581
429
|
this.registerType(constructor);
|
|
582
430
|
}
|
|
583
431
|
ensureInstancesMap(Type) {
|
|
@@ -592,7 +440,7 @@ var StateContainerRegistry = class {
|
|
|
592
440
|
* Get the instances Map for a specific class (public API for stats/debugging)
|
|
593
441
|
*/
|
|
594
442
|
getInstancesMap(Type) {
|
|
595
|
-
return this.instancesByConstructor.get(Type) ||
|
|
443
|
+
return this.instancesByConstructor.get(Type) || EMPTY_INSTANCES_MAP;
|
|
596
444
|
}
|
|
597
445
|
/**
|
|
598
446
|
* Directly insert an instance entry into the registry without going through
|
|
@@ -609,10 +457,13 @@ var StateContainerRegistry = class {
|
|
|
609
457
|
const instances = this.ensureInstancesMap(Type);
|
|
610
458
|
const existingEntry = instances.get(instanceKey);
|
|
611
459
|
if (existingEntry && existingEntry.instance !== instance && !existingEntry.instance.$blac.disposed) existingEntry.instance.dispose();
|
|
612
|
-
|
|
460
|
+
const entry = {
|
|
613
461
|
instance,
|
|
462
|
+
key: instanceKey,
|
|
614
463
|
refs
|
|
615
|
-
}
|
|
464
|
+
};
|
|
465
|
+
instances.set(instanceKey, entry);
|
|
466
|
+
this._entryById.set(instance.$blac.id, entry);
|
|
616
467
|
}
|
|
617
468
|
/**
|
|
618
469
|
* Resolve the storage key for an instance. This is the single source of truth
|
|
@@ -620,7 +471,7 @@ var StateContainerRegistry = class {
|
|
|
620
471
|
* an args-derived key is never dropped (instance leaks).
|
|
621
472
|
*
|
|
622
473
|
* Resolution order (explicit beats derived):
|
|
623
|
-
* explicit key
|
|
474
|
+
* explicit key \> `static key(args)` \> structural hash of args \> default sentinel.
|
|
624
475
|
*
|
|
625
476
|
* @param Type - The StateContainer class constructor
|
|
626
477
|
* @param instanceKey - Explicit key, or undefined to derive from args
|
|
@@ -661,20 +512,19 @@ var StateContainerRegistry = class {
|
|
|
661
512
|
* wrapper; `useBloc` and `watch` address a pre-resolved key here.
|
|
662
513
|
* @param Type - The StateContainer class constructor
|
|
663
514
|
* @param instanceKey - Pre-resolved instance key (defaults to 'default')
|
|
664
|
-
* @param options - Acquisition options
|
|
665
|
-
*
|
|
666
|
-
*
|
|
667
|
-
*
|
|
515
|
+
* @param options - Acquisition options: `canCreate` (create when absent,
|
|
516
|
+
* default true), `countRef` (add a reference, default true), `refId`
|
|
517
|
+
* (named reference for debugging, auto-generated when omitted),
|
|
518
|
+
* `dependent` — the `depend()`-owner resolving this instance, recorded so
|
|
519
|
+
* its dependent edge is released on the owner's disposal — and
|
|
520
|
+
* `sweepIfUnowned`, for callers that create speculatively and claim
|
|
521
|
+
* ownership later (see {@link _scheduleSweep}).
|
|
668
522
|
* @returns The state container instance
|
|
669
523
|
*/
|
|
670
524
|
acquire(Type, instanceKey, options = {}) {
|
|
671
525
|
const { canCreate = true, countRef = true } = options;
|
|
672
526
|
const args = options.args;
|
|
673
527
|
const resolvedKey = this.resolveKey(Type, instanceKey, args);
|
|
674
|
-
const config = {
|
|
675
|
-
instanceId: resolvedKey,
|
|
676
|
-
args
|
|
677
|
-
};
|
|
678
528
|
const instances = this.ensureInstancesMap(Type);
|
|
679
529
|
let entry = instances.get(resolvedKey);
|
|
680
530
|
if (entry?.instance.$blac.disposed) {
|
|
@@ -682,9 +532,9 @@ var StateContainerRegistry = class {
|
|
|
682
532
|
entry = void 0;
|
|
683
533
|
}
|
|
684
534
|
if (entry) {
|
|
685
|
-
if (
|
|
535
|
+
if (IS_DEV && args !== void 0 && entry.args !== void 0) {
|
|
686
536
|
const incomingKey = structuralKey(args);
|
|
687
|
-
const storedKey = structuralKey(entry.args);
|
|
537
|
+
const storedKey = entry.argsKey ??= structuralKey(entry.args);
|
|
688
538
|
if (incomingKey !== storedKey) console.warn(`${BLAC_ERROR_PREFIX} ${Type.name} instance key "${resolvedKey}" was acquired with different args. Existing args: ${storedKey}, new args: ${incomingKey}. The existing instance will be reused. If distinct args should produce distinct instances, either remove the explicit instanceKey or provide a \`static key\` function that reflects the difference.`);
|
|
689
539
|
}
|
|
690
540
|
if (countRef) {
|
|
@@ -693,10 +543,20 @@ var StateContainerRegistry = class {
|
|
|
693
543
|
this.assertRefLimit(Type, resolvedKey, entry.refs.size);
|
|
694
544
|
this.emit("refAcquired", entry.instance, refId);
|
|
695
545
|
}
|
|
546
|
+
if (options.dependent) {
|
|
547
|
+
(entry.dependents ??= /* @__PURE__ */ new Set()).add(options.dependent);
|
|
548
|
+
this._recordDependentEdge(options.dependent, Type, resolvedKey);
|
|
549
|
+
}
|
|
550
|
+
this._syncActivation(entry);
|
|
696
551
|
return entry.instance;
|
|
697
552
|
}
|
|
698
553
|
if (!canCreate) throw new Error(`${BLAC_ERROR_PREFIX} ${Type.name} instance "${resolvedKey}" not found and creation is disabled.`);
|
|
699
554
|
this.assertInstanceLimit(Type, instances.size);
|
|
555
|
+
const config = {
|
|
556
|
+
instanceId: resolvedKey,
|
|
557
|
+
args,
|
|
558
|
+
registry: this
|
|
559
|
+
};
|
|
700
560
|
const instance = new Type();
|
|
701
561
|
instance[INIT_CONFIG](config);
|
|
702
562
|
const initialRefs = /* @__PURE__ */ new Map();
|
|
@@ -705,16 +565,45 @@ var StateContainerRegistry = class {
|
|
|
705
565
|
initialRefId = options.refId ?? `_auto_${this._autoRefIdCounter++}`;
|
|
706
566
|
initialRefs.set(initialRefId, 1);
|
|
707
567
|
}
|
|
708
|
-
|
|
568
|
+
const newEntry = {
|
|
709
569
|
instance,
|
|
570
|
+
key: resolvedKey,
|
|
710
571
|
refs: initialRefs,
|
|
711
572
|
args
|
|
712
|
-
}
|
|
573
|
+
};
|
|
574
|
+
if (options.dependent) {
|
|
575
|
+
(newEntry.dependents ??= /* @__PURE__ */ new Set()).add(options.dependent);
|
|
576
|
+
this._recordDependentEdge(options.dependent, Type, resolvedKey);
|
|
577
|
+
}
|
|
578
|
+
instances.set(resolvedKey, newEntry);
|
|
579
|
+
this._entryById.set(instance.$blac.id, newEntry);
|
|
713
580
|
this.registerType(Type);
|
|
714
581
|
if (initialRefId) this.emit("refAcquired", instance, initialRefId);
|
|
582
|
+
this._syncActivation(newEntry);
|
|
583
|
+
if (options.sweepIfUnowned && this._hasNoOwners(newEntry)) this._scheduleSweep(Type, newEntry);
|
|
715
584
|
return instance;
|
|
716
585
|
}
|
|
717
586
|
/**
|
|
587
|
+
* Speculative creates (`useBloc`'s render-time create) leak forever when the
|
|
588
|
+
* render is discarded or never commits — SSR has no commit at all, so nothing
|
|
589
|
+
* ever claims ownership. Sweep at the end of the microtask unless the entry
|
|
590
|
+
* gained an owner or is keepAlive.
|
|
591
|
+
*
|
|
592
|
+
* Opt-in, not automatic: a bare `ensure()` hands the instance to a caller
|
|
593
|
+
* that legitimately holds it without a ref, and sweeping those would make
|
|
594
|
+
* `ensure` unusable across an `await`.
|
|
595
|
+
*/
|
|
596
|
+
_scheduleSweep(Type, entry) {
|
|
597
|
+
queueMicrotask(() => {
|
|
598
|
+
const instances = this.instancesByConstructor.get(Type);
|
|
599
|
+
if (instances?.get(entry.key) !== entry) return;
|
|
600
|
+
if (entry.instance.$blac.disposed) return;
|
|
601
|
+
if (!this._isUnowned(Type, entry)) return;
|
|
602
|
+
entry.instance.dispose();
|
|
603
|
+
instances.delete(entry.key);
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
718
607
|
* Borrow an existing instance without adding a ref (borrowing semantics).
|
|
719
608
|
* Tracks cross-bloc dependency for reactive updates.
|
|
720
609
|
*
|
|
@@ -724,7 +613,7 @@ var StateContainerRegistry = class {
|
|
|
724
613
|
* @returns The state container instance
|
|
725
614
|
* @throws Error if instance doesn't exist
|
|
726
615
|
*/
|
|
727
|
-
borrow(Type, instanceKey =
|
|
616
|
+
borrow(Type, instanceKey = DEFAULT_STRUCTURAL_KEY) {
|
|
728
617
|
return this.acquire(Type, instanceKey, {
|
|
729
618
|
canCreate: false,
|
|
730
619
|
countRef: false
|
|
@@ -739,7 +628,7 @@ var StateContainerRegistry = class {
|
|
|
739
628
|
* @param instanceKey - Pre-resolved instance key (defaults to 'default')
|
|
740
629
|
* @returns Discriminated union with either the instance or an error
|
|
741
630
|
*/
|
|
742
|
-
borrowSafe(Type, instanceKey =
|
|
631
|
+
borrowSafe(Type, instanceKey = DEFAULT_STRUCTURAL_KEY) {
|
|
743
632
|
try {
|
|
744
633
|
return {
|
|
745
634
|
error: null,
|
|
@@ -785,7 +674,7 @@ var StateContainerRegistry = class {
|
|
|
785
674
|
* @param forceDispose - Force immediate disposal regardless of refs
|
|
786
675
|
* @param refId - The specific ref to remove; removes one arbitrary ref if omitted
|
|
787
676
|
*/
|
|
788
|
-
release(Type, instanceKey =
|
|
677
|
+
release(Type, instanceKey = DEFAULT_STRUCTURAL_KEY, forceDispose = false, refId) {
|
|
789
678
|
const instances = this.ensureInstancesMap(Type);
|
|
790
679
|
const entry = instances.get(instanceKey);
|
|
791
680
|
if (!entry) return;
|
|
@@ -810,20 +699,12 @@ var StateContainerRegistry = class {
|
|
|
810
699
|
}
|
|
811
700
|
}
|
|
812
701
|
if (releasedRefId) this.emit("refReleased", entry.instance, releasedRefId);
|
|
813
|
-
|
|
814
|
-
if (entry.refs.size === 0 && !keepAlive) {
|
|
815
|
-
const deps = entry.instance.$blac.dependencies;
|
|
702
|
+
if (this._isUnowned(Type, entry)) {
|
|
816
703
|
if (!entry.instance.$blac.disposed) entry.instance.dispose();
|
|
817
704
|
instances.delete(instanceKey);
|
|
818
|
-
|
|
819
|
-
const depInstances = this.ensureInstancesMap(DepType);
|
|
820
|
-
const depEntry = depInstances.get(depKey);
|
|
821
|
-
if (depEntry && depEntry.refs.size === 0 && !isKeepAliveClass(DepType) && !depEntry.instance.$blac.disposed) {
|
|
822
|
-
depEntry.instance.dispose();
|
|
823
|
-
depInstances.delete(depKey);
|
|
824
|
-
}
|
|
825
|
-
}
|
|
705
|
+
return;
|
|
826
706
|
}
|
|
707
|
+
this._syncActivation(entry);
|
|
827
708
|
}
|
|
828
709
|
/**
|
|
829
710
|
* Get all instances of a specific type.
|
|
@@ -833,7 +714,7 @@ var StateContainerRegistry = class {
|
|
|
833
714
|
getAll(Type) {
|
|
834
715
|
const instances = this.ensureInstancesMap(Type);
|
|
835
716
|
const result = [];
|
|
836
|
-
for (const entry of instances.values()) result.push(entry.instance);
|
|
717
|
+
for (const entry of instances.values()) if (!entry.instance.$blac.disposed) result.push(entry.instance);
|
|
837
718
|
return result;
|
|
838
719
|
}
|
|
839
720
|
/**
|
|
@@ -870,7 +751,7 @@ var StateContainerRegistry = class {
|
|
|
870
751
|
* @param instanceKey - Pre-resolved instance key (defaults to 'default')
|
|
871
752
|
* @returns Current ref count (0 if instance doesn't exist)
|
|
872
753
|
*/
|
|
873
|
-
getRefCount(Type, instanceKey =
|
|
754
|
+
getRefCount(Type, instanceKey = DEFAULT_STRUCTURAL_KEY) {
|
|
874
755
|
return this.ensureInstancesMap(Type).get(instanceKey)?.refs.size ?? 0;
|
|
875
756
|
}
|
|
876
757
|
/**
|
|
@@ -881,13 +762,23 @@ var StateContainerRegistry = class {
|
|
|
881
762
|
* @param instanceKey - Pre-resolved instance key (defaults to 'default')
|
|
882
763
|
* @returns Array of ref ID strings (empty if instance doesn't exist)
|
|
883
764
|
*/
|
|
884
|
-
getRefIds(Type, instanceKey =
|
|
765
|
+
getRefIds(Type, instanceKey = DEFAULT_STRUCTURAL_KEY) {
|
|
885
766
|
const instances = this.instancesByConstructor.get(Type);
|
|
886
767
|
if (!instances) return [];
|
|
887
768
|
const entry = instances.get(instanceKey);
|
|
888
769
|
return entry ? Array.from(entry.refs.keys()) : [];
|
|
889
770
|
}
|
|
890
771
|
/**
|
|
772
|
+
* Get all active reference IDs for an instance by its `$blac.id`, without
|
|
773
|
+
* needing the owning Type. Used by `PluginContext.getRefIds`.
|
|
774
|
+
* @param instanceId - The instance's `$blac.id`
|
|
775
|
+
* @returns Array of ref ID strings (empty if instance doesn't exist)
|
|
776
|
+
*/
|
|
777
|
+
getRefIdsById(instanceId) {
|
|
778
|
+
const entry = this._entryById.get(instanceId);
|
|
779
|
+
return entry ? Array.from(entry.refs.keys()) : [];
|
|
780
|
+
}
|
|
781
|
+
/**
|
|
891
782
|
* Check if an instance exists.
|
|
892
783
|
*
|
|
893
784
|
* @internal Internal key tier; public callers use the args-based `hasInstance`.
|
|
@@ -895,7 +786,7 @@ var StateContainerRegistry = class {
|
|
|
895
786
|
* @param instanceKey - Pre-resolved instance key (defaults to 'default')
|
|
896
787
|
* @returns true if instance exists
|
|
897
788
|
*/
|
|
898
|
-
hasInstance(Type, instanceKey =
|
|
789
|
+
hasInstance(Type, instanceKey = DEFAULT_STRUCTURAL_KEY) {
|
|
899
790
|
return this.ensureInstancesMap(Type).has(instanceKey);
|
|
900
791
|
}
|
|
901
792
|
/**
|
|
@@ -907,7 +798,6 @@ var StateContainerRegistry = class {
|
|
|
907
798
|
clearAll() {
|
|
908
799
|
for (const Type of this.types) this.clear(Type);
|
|
909
800
|
this.types.clear();
|
|
910
|
-
this.registeredTypeNames.clear();
|
|
911
801
|
}
|
|
912
802
|
/**
|
|
913
803
|
* Get registry statistics for debugging.
|
|
@@ -942,13 +832,14 @@ var StateContainerRegistry = class {
|
|
|
942
832
|
* @returns Unsubscribe function
|
|
943
833
|
*/
|
|
944
834
|
on(event, listener) {
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
835
|
+
let instance = this.listeners.get(event);
|
|
836
|
+
if (!instance) {
|
|
837
|
+
instance = /* @__PURE__ */ new Set();
|
|
838
|
+
this.listeners.set(event, instance);
|
|
839
|
+
}
|
|
948
840
|
instance.add(listener);
|
|
949
|
-
if (event === "stateChanged") this._stateChangedListenerCount++;
|
|
950
841
|
return () => {
|
|
951
|
-
|
|
842
|
+
this.listeners.get(event)?.delete(listener);
|
|
952
843
|
};
|
|
953
844
|
}
|
|
954
845
|
emit(event, ...args) {
|
|
@@ -966,7 +857,7 @@ var StateContainerRegistry = class {
|
|
|
966
857
|
* @internal - Called by StateContainer.applyState
|
|
967
858
|
*/
|
|
968
859
|
notifyStateChanged(container, previousState, newState) {
|
|
969
|
-
if (this.
|
|
860
|
+
if (!this.hasStateChangedListeners) return;
|
|
970
861
|
if (!this._pendingStateChanges) {
|
|
971
862
|
this._pendingStateChanges = [];
|
|
972
863
|
queueMicrotask(() => this.flushStateChanged());
|
|
@@ -977,6 +868,15 @@ var StateContainerRegistry = class {
|
|
|
977
868
|
newState
|
|
978
869
|
]);
|
|
979
870
|
}
|
|
871
|
+
/**
|
|
872
|
+
* Deliver one event per emit, in order — deliberately NOT coalesced.
|
|
873
|
+
*
|
|
874
|
+
* This is a transition log: devtools, time-travel debugging and perf
|
|
875
|
+
* monitoring need every intermediate `prev`/`next`, which coalescing would
|
|
876
|
+
* destroy. The plugin `onStateChange` bridge is the coalesced, `PathSet`-
|
|
877
|
+
* carrying lane (see `PluginManager.setupLifecycleHooks`); the two differ on
|
|
878
|
+
* purpose, so a listener picks the lane that matches what it needs.
|
|
879
|
+
*/
|
|
980
880
|
flushStateChanged() {
|
|
981
881
|
const pending = this._pendingStateChanges;
|
|
982
882
|
this._pendingStateChanges = null;
|
|
@@ -986,20 +886,10 @@ var StateContainerRegistry = class {
|
|
|
986
886
|
};
|
|
987
887
|
/**
|
|
988
888
|
* Global default registry instance
|
|
889
|
+
* @public
|
|
989
890
|
*/
|
|
990
891
|
const globalRegistry = new StateContainerRegistry();
|
|
991
|
-
/**
|
|
992
|
-
* Global plugin manager (initialized lazily)
|
|
993
|
-
*/
|
|
994
|
-
let _globalPluginManager = null;
|
|
995
|
-
/**
|
|
996
|
-
* Get the global plugin manager
|
|
997
|
-
*/
|
|
998
|
-
function getPluginManager() {
|
|
999
|
-
if (!_globalPluginManager) _globalPluginManager = createPluginManager(globalRegistry);
|
|
1000
|
-
return _globalPluginManager;
|
|
1001
|
-
}
|
|
1002
892
|
//#endregion
|
|
1003
|
-
export {
|
|
893
|
+
export { resetBlacConfig as _, ON_DISPOSE as a, WITH_TRACKED_STATE as c, isExcludedFromDevTools as d, isKeepAliveClass as f, getBlacConfig as g, configureBlac as h, INIT_CONFIG as i, getBlacName as l, IS_DEV as m, globalRegistry as n, REMOVE_DEPS_OWNER as o, BLAC_STATIC_PROPS as p, APPLY_DEPS as r, SET_ACTIVE as s, StateContainerRegistry as t, getClassEquality as u, shallowEqualState as v };
|
|
1004
894
|
|
|
1005
|
-
//# sourceMappingURL=StateContainerRegistry-
|
|
895
|
+
//# sourceMappingURL=StateContainerRegistry-BsH_s0pJ.js.map
|