@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,23 +8,26 @@ 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,
|
|
22
|
-
maxInstancesPerType:
|
|
23
|
-
maxRefsPerInstance:
|
|
24
|
-
maxEmitsPerSecond:
|
|
24
|
+
maxInstancesPerType: 1e5,
|
|
25
|
+
maxRefsPerInstance: 1e5,
|
|
26
|
+
maxEmitsPerSecond: 1e3
|
|
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,325 +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
|
-
for (const { plugin, config } of this.plugins.values()) {
|
|
254
|
-
if (!config.enabled) continue;
|
|
255
|
-
const hook = plugin.onStateChange;
|
|
256
|
-
if (typeof hook !== "function") continue;
|
|
257
|
-
try {
|
|
258
|
-
hook.call(plugin, this.buildContext(container), prev, next, paths);
|
|
259
|
-
} catch (error) {
|
|
260
|
-
console.error(`[BlaC] Error in plugin "${plugin.name}" onStateChange:`, error);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Notify all plugins of a lifecycle event.
|
|
266
|
-
*
|
|
267
|
-
* Builds a fresh `PluginContext` per dispatch (instance becomes
|
|
268
|
-
* `ctx.container`), so plugins can reach the focal bloc through
|
|
269
|
-
* `ctx.container`.
|
|
270
|
-
*/
|
|
271
|
-
notifyPlugins(hookName, instance, ...extraArgs) {
|
|
272
|
-
for (const { plugin, config } of this.plugins.values()) {
|
|
273
|
-
if (!config.enabled) continue;
|
|
274
|
-
const hook = plugin[hookName];
|
|
275
|
-
if (typeof hook !== "function") continue;
|
|
276
|
-
try {
|
|
277
|
-
hook.call(plugin, this.buildContext(instance), ...extraArgs);
|
|
278
|
-
} catch (error) {
|
|
279
|
-
console.error(`[BlaC] Error in plugin "${plugin.name}" ${hookName}:`, error);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* Build a `PluginContext` for a given focal container. The context is
|
|
285
|
-
* cheap to build — its methods close over `this.registry` directly —
|
|
286
|
-
* so we create one per dispatch rather than caching per container.
|
|
287
|
-
* This sidesteps the lifetime question of "when do we evict a cached
|
|
288
|
-
* context?" and keeps `paths`-vs-`container` lifetimes cleanly
|
|
289
|
-
* separated.
|
|
290
|
-
*/
|
|
291
|
-
buildContext(container) {
|
|
292
|
-
const registry = this.registry;
|
|
293
|
-
return {
|
|
294
|
-
container,
|
|
295
|
-
getInstanceMetadata: (instance) => {
|
|
296
|
-
return {
|
|
297
|
-
id: instance.$blac.id,
|
|
298
|
-
className: instance.constructor.name,
|
|
299
|
-
isDisposed: instance.$blac.disposed,
|
|
300
|
-
name: instance.$blac.name,
|
|
301
|
-
createdAt: instance.$blac.createdAt,
|
|
302
|
-
state: instance.state,
|
|
303
|
-
hydrationStatus: instance.$blac.hydration.status,
|
|
304
|
-
isHydrated: instance.$blac.hydration.isHydrated,
|
|
305
|
-
hydrationError: instance.$blac.hydration.error,
|
|
306
|
-
changedWhileHydrating: instance.$blac.hydration.changedWhileHydrating,
|
|
307
|
-
args: instance.args
|
|
308
|
-
};
|
|
309
|
-
},
|
|
310
|
-
getState: (instance) => {
|
|
311
|
-
return instance.state;
|
|
312
|
-
},
|
|
313
|
-
getHydrationStatus: (instance) => {
|
|
314
|
-
return instance.$blac.hydration.status;
|
|
315
|
-
},
|
|
316
|
-
startHydration: (instance) => {
|
|
317
|
-
instance.$blac.hydration.begin();
|
|
318
|
-
},
|
|
319
|
-
applyHydratedState: (instance, state) => {
|
|
320
|
-
return instance.$blac.hydration.apply(state);
|
|
321
|
-
},
|
|
322
|
-
finishHydration: (instance) => {
|
|
323
|
-
instance.$blac.hydration.finish();
|
|
324
|
-
},
|
|
325
|
-
failHydration: (instance, error) => {
|
|
326
|
-
instance.$blac.hydration.fail(error);
|
|
327
|
-
},
|
|
328
|
-
waitForHydration: (instance) => {
|
|
329
|
-
return instance.$blac.hydration.wait();
|
|
330
|
-
},
|
|
331
|
-
queryInstances: (typeClass) => {
|
|
332
|
-
return registry.getAll(typeClass);
|
|
333
|
-
},
|
|
334
|
-
getAllTypes: () => {
|
|
335
|
-
return registry.getTypes();
|
|
336
|
-
},
|
|
337
|
-
getStats: () => {
|
|
338
|
-
return registry.getStats();
|
|
339
|
-
},
|
|
340
|
-
getRefIds: (instanceId) => {
|
|
341
|
-
for (const Type of registry.getTypes()) {
|
|
342
|
-
const map = registry.getInstancesMap(Type);
|
|
343
|
-
for (const [, entry] of map) if (entry.instance.$blac.id === instanceId) return Array.from(entry.refs.keys());
|
|
344
|
-
}
|
|
345
|
-
return [];
|
|
346
|
-
}
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
/**
|
|
350
|
-
* Check if plugin should be enabled based on environment
|
|
351
|
-
*/
|
|
352
|
-
shouldEnablePlugin(config) {
|
|
353
|
-
if (!config.enabled) return false;
|
|
354
|
-
if (config.environment === "all") return true;
|
|
355
|
-
return this.getCurrentEnvironment() === config.environment;
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* Get current environment
|
|
359
|
-
*/
|
|
360
|
-
getCurrentEnvironment() {
|
|
361
|
-
if (typeof process !== "undefined") {
|
|
362
|
-
if (process.env.NODE_ENV === "test") return "test";
|
|
363
|
-
if (process.env.NODE_ENV === "production") return "production";
|
|
364
|
-
return "development";
|
|
365
|
-
}
|
|
366
|
-
return "development";
|
|
367
|
-
}
|
|
368
|
-
};
|
|
369
|
-
/**
|
|
370
|
-
* Create a plugin manager instance
|
|
371
|
-
* @param registry - The StateContainerRegistry to monitor for lifecycle events
|
|
372
|
-
* @returns A new PluginManager instance
|
|
373
|
-
*/
|
|
374
|
-
function createPluginManager(registry) {
|
|
375
|
-
return new PluginManager(registry);
|
|
376
|
-
}
|
|
377
|
-
//#endregion
|
|
378
61
|
//#region src/constants.ts
|
|
379
62
|
/**
|
|
380
63
|
* Default configuration constants for BlaC
|
|
@@ -382,19 +65,6 @@ function createPluginManager(registry) {
|
|
|
382
65
|
* Centralized location for all magic numbers and default values.
|
|
383
66
|
*/
|
|
384
67
|
/**
|
|
385
|
-
* Default configuration constants for BlaC
|
|
386
|
-
*/
|
|
387
|
-
const BLAC_DEFAULTS = {
|
|
388
|
-
/**
|
|
389
|
-
* Default instance key for shared instances
|
|
390
|
-
*/
|
|
391
|
-
DEFAULT_INSTANCE_KEY: "default",
|
|
392
|
-
/**
|
|
393
|
-
* Maximum getter nesting depth (prevents infinite recursion)
|
|
394
|
-
*/
|
|
395
|
-
MAX_GETTER_DEPTH: 10
|
|
396
|
-
};
|
|
397
|
-
/**
|
|
398
68
|
* Static property names for StateContainer classes
|
|
399
69
|
* Used for feature flags and configuration on bloc classes
|
|
400
70
|
*/
|
|
@@ -419,19 +89,42 @@ const BLAC_STATIC_PROPS = {
|
|
|
419
89
|
* instead of using a structural hash of `args`. Allows blocs to ignore
|
|
420
90
|
* non-identity fields (e.g., `readonly` flags) while still keying by id.
|
|
421
91
|
*/
|
|
422
|
-
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"
|
|
423
98
|
};
|
|
424
99
|
/**
|
|
425
100
|
* Standard error message prefix
|
|
426
101
|
*/
|
|
427
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";
|
|
428
120
|
//#endregion
|
|
429
121
|
//#region src/utils/static-props.ts
|
|
430
122
|
/**
|
|
431
123
|
* Utility functions for accessing static properties on StateContainer classes
|
|
432
124
|
*/
|
|
433
125
|
/**
|
|
434
|
-
* 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.
|
|
435
128
|
* Type-safe helper that avoids (Type as any) casts
|
|
436
129
|
*
|
|
437
130
|
* @param Type - The class constructor
|
|
@@ -443,8 +136,20 @@ function getStaticProp(Type, propName, defaultValue) {
|
|
|
443
136
|
return Type[propName] ?? defaultValue;
|
|
444
137
|
}
|
|
445
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
|
+
/**
|
|
446
150
|
* Check if a class is marked as keepAlive.
|
|
447
151
|
* KeepAlive classes are never auto-disposed when ref count reaches 0.
|
|
152
|
+
* Inherited: a subclass keeps a base class's `keepAlive` unless overridden.
|
|
448
153
|
* @param Type - The class constructor to check
|
|
449
154
|
* @returns true if the class has `static keepAlive = true`
|
|
450
155
|
*/
|
|
@@ -454,6 +159,7 @@ function isKeepAliveClass(Type) {
|
|
|
454
159
|
/**
|
|
455
160
|
* Check if a class should be excluded from DevTools.
|
|
456
161
|
* Used to prevent infinite loops when DevTools tracks itself.
|
|
162
|
+
* Inherited: a subclass keeps a base class's exclusion unless overridden.
|
|
457
163
|
* @param Type - The class constructor to check
|
|
458
164
|
* @returns true if the class has `static __excludeFromDevTools = true`
|
|
459
165
|
*/
|
|
@@ -462,6 +168,7 @@ function isExcludedFromDevTools(Type) {
|
|
|
462
168
|
}
|
|
463
169
|
/**
|
|
464
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.
|
|
465
172
|
* @param Type - The class constructor to check
|
|
466
173
|
* @returns the equality function or `undefined`
|
|
467
174
|
*/
|
|
@@ -470,13 +177,26 @@ function getClassEquality(Type) {
|
|
|
470
177
|
return typeof fn === "function" ? fn : void 0;
|
|
471
178
|
}
|
|
472
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
|
+
/**
|
|
473
191
|
* Get the per-class key function set via `@blac({ key })` or `static key = …`, if any.
|
|
474
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.
|
|
475
195
|
* @param Type - The class constructor to check
|
|
476
196
|
* @returns the key function or `undefined`
|
|
477
197
|
*/
|
|
478
198
|
function getClassKey(Type) {
|
|
479
|
-
const fn =
|
|
199
|
+
const fn = getOwnStaticProp(Type, BLAC_STATIC_PROPS.KEY);
|
|
480
200
|
return typeof fn === "function" ? fn : void 0;
|
|
481
201
|
}
|
|
482
202
|
//#endregion
|
|
@@ -493,11 +213,24 @@ const DEFAULT_STRUCTURAL_KEY = "default";
|
|
|
493
213
|
* - Object keys are sorted for order-independence.
|
|
494
214
|
* - Arrays keep their insertion order.
|
|
495
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.
|
|
496
218
|
*/
|
|
219
|
+
const keyCache = /* @__PURE__ */ new WeakMap();
|
|
497
220
|
function structuralKey(args) {
|
|
498
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) {
|
|
499
232
|
return JSON.stringify(args, function(_k, v) {
|
|
500
|
-
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)"}")`);
|
|
501
234
|
if (v && typeof v === "object" && !Array.isArray(v)) return Object.keys(v).sort().reduce((o, k) => {
|
|
502
235
|
o[k] = v[k];
|
|
503
236
|
return o;
|
|
@@ -509,7 +242,7 @@ function structuralKey(args) {
|
|
|
509
242
|
//#region src/core/symbols.ts
|
|
510
243
|
/**
|
|
511
244
|
* @internal Apply one owner's (consumer's) deps slice to an instance.
|
|
512
|
-
* Called by framework adapters (e.g.
|
|
245
|
+
* Called by framework adapters (e.g. `@blac/react` useBloc) — not public API.
|
|
513
246
|
*/
|
|
514
247
|
const APPLY_DEPS = Symbol("blac.applyDeps");
|
|
515
248
|
/**
|
|
@@ -518,6 +251,12 @@ const APPLY_DEPS = Symbol("blac.applyDeps");
|
|
|
518
251
|
*/
|
|
519
252
|
const REMOVE_DEPS_OWNER = Symbol("blac.removeDepsOwner");
|
|
520
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
|
+
/**
|
|
521
260
|
* @internal Symbol-keyed configuration entry point on `StateContainer`.
|
|
522
261
|
* Writes the instance's identity fields (`_name`/`_debug`/`_instanceId`),
|
|
523
262
|
* resolves per-class equality, emits the registry `created` event, and runs
|
|
@@ -527,8 +266,27 @@ const REMOVE_DEPS_OWNER = Symbol("blac.removeDepsOwner");
|
|
|
527
266
|
* helpers are the sole callers, mirroring the `APPLY_DEPS` precedent.
|
|
528
267
|
*/
|
|
529
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");
|
|
530
286
|
//#endregion
|
|
531
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();
|
|
532
290
|
/**
|
|
533
291
|
* Central registry for managing StateContainer instances.
|
|
534
292
|
* Handles instance lifecycle, named ref tracking, and lifecycle event emission.
|
|
@@ -542,19 +300,114 @@ const INIT_CONFIG = Symbol("blac.initConfig");
|
|
|
542
300
|
* console.log('State changed:', prev, '->', next);
|
|
543
301
|
* });
|
|
544
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.
|
|
545
309
|
*/
|
|
546
310
|
var StateContainerRegistry = class {
|
|
311
|
+
get hasStateChangedListeners() {
|
|
312
|
+
return this._stateChangedListenerCount > 0;
|
|
313
|
+
}
|
|
547
314
|
constructor() {
|
|
548
315
|
this.instancesByConstructor = /* @__PURE__ */ new WeakMap();
|
|
549
316
|
this.types = /* @__PURE__ */ new Set();
|
|
550
|
-
this.
|
|
317
|
+
this._dependentEdges = /* @__PURE__ */ new WeakMap();
|
|
318
|
+
this._entryById = /* @__PURE__ */ new Map();
|
|
551
319
|
this.listeners = /* @__PURE__ */ new Map();
|
|
552
320
|
this._stateChangedListenerCount = 0;
|
|
553
321
|
this._pendingStateChanges = null;
|
|
554
322
|
this._autoRefIdCounter = 0;
|
|
323
|
+
this.on("disposed", (container) => this._handleDisposed(container));
|
|
555
324
|
}
|
|
556
|
-
|
|
557
|
-
|
|
325
|
+
/**
|
|
326
|
+
* Registry-internal reaction to any instance's `disposed` lifecycle event.
|
|
327
|
+
* If the disposing container is itself tracked in this registry (i.e. it
|
|
328
|
+
* was `acquire()`/`ensure()`'d, not a bare `new`), prune its Map entry and
|
|
329
|
+
* release its dependent edges on whatever it `depend()`'d on.
|
|
330
|
+
*/
|
|
331
|
+
_handleDisposed(container) {
|
|
332
|
+
const Type = container.constructor;
|
|
333
|
+
if (!this._pruneEntry(Type, container)) return;
|
|
334
|
+
const edges = this._dependentEdges.get(container);
|
|
335
|
+
if (!edges) return;
|
|
336
|
+
this._dependentEdges.delete(container);
|
|
337
|
+
for (const [DepType, keys] of edges) for (const depKey of keys) this._releaseDependent(DepType, depKey, container);
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* An entry may be disposed only when nothing owns it: no public refs, no
|
|
341
|
+
* `depend()` dependents, and not keepAlive. Every dispose decision goes
|
|
342
|
+
* through here so `release()` and `_releaseDependent` cannot disagree.
|
|
343
|
+
*/
|
|
344
|
+
_isUnowned(Type, entry) {
|
|
345
|
+
return this._hasNoOwners(entry) && !isKeepAliveClass(Type);
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Pure ownership: refs plus `depend()` dependents, with no keepAlive term.
|
|
349
|
+
* `_isUnowned` is "may be disposed"; this is "nothing is using it", which is
|
|
350
|
+
* what the activation lifecycle keys off — a keepAlive instance still
|
|
351
|
+
* deactivates when its last owner goes.
|
|
352
|
+
*/
|
|
353
|
+
_hasNoOwners(entry) {
|
|
354
|
+
return entry.refs.size === 0 && (entry.dependents === void 0 || entry.dependents.size === 0);
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Single funnel for the 0↔1 ownership transition. `SET_ACTIVE` is idempotent,
|
|
358
|
+
* so every acquire/release path can call this unconditionally rather than
|
|
359
|
+
* each computing the edge itself. Emits `activated`/`deactivated` for
|
|
360
|
+
* plugins to observe the same transition `onActivate`/`onDeactivate` expose
|
|
361
|
+
* to bloc authors — after `SET_ACTIVE` has already run the instance's own
|
|
362
|
+
* hook, so plugins always see a container that has finished reacting.
|
|
363
|
+
*/
|
|
364
|
+
_syncActivation(entry) {
|
|
365
|
+
const transition = entry.instance[SET_ACTIVE](!this._hasNoOwners(entry));
|
|
366
|
+
if (transition === "none") return;
|
|
367
|
+
if (transition === "deactivated") this.emit("deactivated", entry.instance);
|
|
368
|
+
else this.emit("activated", entry.instance, transition.signal);
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Record that `dependent` resolved `Type` at `key`, so the edge can be
|
|
372
|
+
* released on the owner's disposal. Keyed per resolved key, not per type:
|
|
373
|
+
* one `depend()` handle resolves a distinct key for every `args` it is
|
|
374
|
+
* called with, and all of them must be swept.
|
|
375
|
+
*/
|
|
376
|
+
_recordDependentEdge(dependent, Type, key) {
|
|
377
|
+
let byType = this._dependentEdges.get(dependent);
|
|
378
|
+
if (!byType) this._dependentEdges.set(dependent, byType = /* @__PURE__ */ new Map());
|
|
379
|
+
let keys = byType.get(Type);
|
|
380
|
+
if (!keys) byType.set(Type, keys = /* @__PURE__ */ new Set());
|
|
381
|
+
keys.add(key);
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Remove the Map entry for `container`, if this registry is tracking it.
|
|
385
|
+
* @returns true if an entry was found and removed
|
|
386
|
+
*/
|
|
387
|
+
_pruneEntry(Type, container) {
|
|
388
|
+
const id = container._instanceId;
|
|
389
|
+
if (id === void 0) return false;
|
|
390
|
+
const entry = this._entryById.get(id);
|
|
391
|
+
if (entry === void 0 || entry.instance !== container) return false;
|
|
392
|
+
this.instancesByConstructor.get(Type)?.delete(entry.key);
|
|
393
|
+
this._entryById.delete(id);
|
|
394
|
+
return true;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Drop `dependent`'s edge on the `Type`/`key` entry (a `depend()`-resolved
|
|
398
|
+
* instance). When that leaves the entry with no dependents AND no public
|
|
399
|
+
* refs AND it isn't keepAlive, dispose it — this recurses into the same
|
|
400
|
+
* `disposed` listener, so dep-of-dep chains unwind naturally.
|
|
401
|
+
*/
|
|
402
|
+
_releaseDependent(Type, key, dependent) {
|
|
403
|
+
const entry = this.instancesByConstructor.get(Type)?.get(key);
|
|
404
|
+
if (!entry) return;
|
|
405
|
+
entry.dependents?.delete(dependent);
|
|
406
|
+
if (this._isUnowned(Type, entry)) {
|
|
407
|
+
if (!entry.instance.$blac.disposed) entry.instance.dispose();
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
this._syncActivation(entry);
|
|
558
411
|
}
|
|
559
412
|
/**
|
|
560
413
|
* Register a type for lifecycle event tracking
|
|
@@ -569,9 +422,7 @@ var StateContainerRegistry = class {
|
|
|
569
422
|
* @throws Error if type is already registered
|
|
570
423
|
*/
|
|
571
424
|
register(constructor) {
|
|
572
|
-
|
|
573
|
-
if (this.registeredTypeNames.has(className)) throw new Error(`${BLAC_ERROR_PREFIX} Type "${className}" is already registered`);
|
|
574
|
-
this.registeredTypeNames.add(className);
|
|
425
|
+
if (this.types.has(constructor)) throw new Error(`${BLAC_ERROR_PREFIX} Type "${getBlacName(constructor)}" is already registered`);
|
|
575
426
|
this.registerType(constructor);
|
|
576
427
|
}
|
|
577
428
|
ensureInstancesMap(Type) {
|
|
@@ -586,7 +437,7 @@ var StateContainerRegistry = class {
|
|
|
586
437
|
* Get the instances Map for a specific class (public API for stats/debugging)
|
|
587
438
|
*/
|
|
588
439
|
getInstancesMap(Type) {
|
|
589
|
-
return this.instancesByConstructor.get(Type) ||
|
|
440
|
+
return this.instancesByConstructor.get(Type) || EMPTY_INSTANCES_MAP;
|
|
590
441
|
}
|
|
591
442
|
/**
|
|
592
443
|
* Directly insert an instance entry into the registry without going through
|
|
@@ -603,10 +454,13 @@ var StateContainerRegistry = class {
|
|
|
603
454
|
const instances = this.ensureInstancesMap(Type);
|
|
604
455
|
const existingEntry = instances.get(instanceKey);
|
|
605
456
|
if (existingEntry && existingEntry.instance !== instance && !existingEntry.instance.$blac.disposed) existingEntry.instance.dispose();
|
|
606
|
-
|
|
457
|
+
const entry = {
|
|
607
458
|
instance,
|
|
459
|
+
key: instanceKey,
|
|
608
460
|
refs
|
|
609
|
-
}
|
|
461
|
+
};
|
|
462
|
+
instances.set(instanceKey, entry);
|
|
463
|
+
this._entryById.set(instance.$blac.id, entry);
|
|
610
464
|
}
|
|
611
465
|
/**
|
|
612
466
|
* Resolve the storage key for an instance. This is the single source of truth
|
|
@@ -614,7 +468,7 @@ var StateContainerRegistry = class {
|
|
|
614
468
|
* an args-derived key is never dropped (instance leaks).
|
|
615
469
|
*
|
|
616
470
|
* Resolution order (explicit beats derived):
|
|
617
|
-
* explicit key
|
|
471
|
+
* explicit key \> `static key(args)` \> structural hash of args \> default sentinel.
|
|
618
472
|
*
|
|
619
473
|
* @param Type - The StateContainer class constructor
|
|
620
474
|
* @param instanceKey - Explicit key, or undefined to derive from args
|
|
@@ -655,20 +509,19 @@ var StateContainerRegistry = class {
|
|
|
655
509
|
* wrapper; `useBloc` and `watch` address a pre-resolved key here.
|
|
656
510
|
* @param Type - The StateContainer class constructor
|
|
657
511
|
* @param instanceKey - Pre-resolved instance key (defaults to 'default')
|
|
658
|
-
* @param options - Acquisition options
|
|
659
|
-
*
|
|
660
|
-
*
|
|
661
|
-
*
|
|
512
|
+
* @param options - Acquisition options: `canCreate` (create when absent,
|
|
513
|
+
* default true), `countRef` (add a reference, default true), `refId`
|
|
514
|
+
* (named reference for debugging, auto-generated when omitted),
|
|
515
|
+
* `dependent` — the `depend()`-owner resolving this instance, recorded so
|
|
516
|
+
* its dependent edge is released on the owner's disposal — and
|
|
517
|
+
* `sweepIfUnowned`, for callers that create speculatively and claim
|
|
518
|
+
* ownership later (see {@link _scheduleSweep}).
|
|
662
519
|
* @returns The state container instance
|
|
663
520
|
*/
|
|
664
521
|
acquire(Type, instanceKey, options = {}) {
|
|
665
522
|
const { canCreate = true, countRef = true } = options;
|
|
666
523
|
const args = options.args;
|
|
667
524
|
const resolvedKey = this.resolveKey(Type, instanceKey, args);
|
|
668
|
-
const config = {
|
|
669
|
-
instanceId: resolvedKey,
|
|
670
|
-
args
|
|
671
|
-
};
|
|
672
525
|
const instances = this.ensureInstancesMap(Type);
|
|
673
526
|
let entry = instances.get(resolvedKey);
|
|
674
527
|
if (entry?.instance.$blac.disposed) {
|
|
@@ -676,9 +529,9 @@ var StateContainerRegistry = class {
|
|
|
676
529
|
entry = void 0;
|
|
677
530
|
}
|
|
678
531
|
if (entry) {
|
|
679
|
-
if (
|
|
532
|
+
if (IS_DEV && args !== void 0 && entry.args !== void 0) {
|
|
680
533
|
const incomingKey = structuralKey(args);
|
|
681
|
-
const storedKey = structuralKey(entry.args);
|
|
534
|
+
const storedKey = entry.argsKey ??= structuralKey(entry.args);
|
|
682
535
|
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.`);
|
|
683
536
|
}
|
|
684
537
|
if (countRef) {
|
|
@@ -687,10 +540,19 @@ var StateContainerRegistry = class {
|
|
|
687
540
|
this.assertRefLimit(Type, resolvedKey, entry.refs.size);
|
|
688
541
|
this.emit("refAcquired", entry.instance, refId);
|
|
689
542
|
}
|
|
543
|
+
if (options.dependent) {
|
|
544
|
+
(entry.dependents ??= /* @__PURE__ */ new Set()).add(options.dependent);
|
|
545
|
+
this._recordDependentEdge(options.dependent, Type, resolvedKey);
|
|
546
|
+
}
|
|
547
|
+
this._syncActivation(entry);
|
|
690
548
|
return entry.instance;
|
|
691
549
|
}
|
|
692
550
|
if (!canCreate) throw new Error(`${BLAC_ERROR_PREFIX} ${Type.name} instance "${resolvedKey}" not found and creation is disabled.`);
|
|
693
551
|
this.assertInstanceLimit(Type, instances.size);
|
|
552
|
+
const config = {
|
|
553
|
+
instanceId: resolvedKey,
|
|
554
|
+
args
|
|
555
|
+
};
|
|
694
556
|
const instance = new Type();
|
|
695
557
|
instance[INIT_CONFIG](config);
|
|
696
558
|
const initialRefs = /* @__PURE__ */ new Map();
|
|
@@ -699,16 +561,45 @@ var StateContainerRegistry = class {
|
|
|
699
561
|
initialRefId = options.refId ?? `_auto_${this._autoRefIdCounter++}`;
|
|
700
562
|
initialRefs.set(initialRefId, 1);
|
|
701
563
|
}
|
|
702
|
-
|
|
564
|
+
const newEntry = {
|
|
703
565
|
instance,
|
|
566
|
+
key: resolvedKey,
|
|
704
567
|
refs: initialRefs,
|
|
705
568
|
args
|
|
706
|
-
}
|
|
569
|
+
};
|
|
570
|
+
if (options.dependent) {
|
|
571
|
+
(newEntry.dependents ??= /* @__PURE__ */ new Set()).add(options.dependent);
|
|
572
|
+
this._recordDependentEdge(options.dependent, Type, resolvedKey);
|
|
573
|
+
}
|
|
574
|
+
instances.set(resolvedKey, newEntry);
|
|
575
|
+
this._entryById.set(instance.$blac.id, newEntry);
|
|
707
576
|
this.registerType(Type);
|
|
708
577
|
if (initialRefId) this.emit("refAcquired", instance, initialRefId);
|
|
578
|
+
this._syncActivation(newEntry);
|
|
579
|
+
if (options.sweepIfUnowned && this._hasNoOwners(newEntry)) this._scheduleSweep(Type, newEntry);
|
|
709
580
|
return instance;
|
|
710
581
|
}
|
|
711
582
|
/**
|
|
583
|
+
* Speculative creates (`useBloc`'s render-time create) leak forever when the
|
|
584
|
+
* render is discarded or never commits — SSR has no commit at all, so nothing
|
|
585
|
+
* ever claims ownership. Sweep at the end of the microtask unless the entry
|
|
586
|
+
* gained an owner or is keepAlive.
|
|
587
|
+
*
|
|
588
|
+
* Opt-in, not automatic: a bare `ensure()` hands the instance to a caller
|
|
589
|
+
* that legitimately holds it without a ref, and sweeping those would make
|
|
590
|
+
* `ensure` unusable across an `await`.
|
|
591
|
+
*/
|
|
592
|
+
_scheduleSweep(Type, entry) {
|
|
593
|
+
queueMicrotask(() => {
|
|
594
|
+
const instances = this.instancesByConstructor.get(Type);
|
|
595
|
+
if (instances?.get(entry.key) !== entry) return;
|
|
596
|
+
if (entry.instance.$blac.disposed) return;
|
|
597
|
+
if (!this._isUnowned(Type, entry)) return;
|
|
598
|
+
entry.instance.dispose();
|
|
599
|
+
instances.delete(entry.key);
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
712
603
|
* Borrow an existing instance without adding a ref (borrowing semantics).
|
|
713
604
|
* Tracks cross-bloc dependency for reactive updates.
|
|
714
605
|
*
|
|
@@ -718,7 +609,7 @@ var StateContainerRegistry = class {
|
|
|
718
609
|
* @returns The state container instance
|
|
719
610
|
* @throws Error if instance doesn't exist
|
|
720
611
|
*/
|
|
721
|
-
borrow(Type, instanceKey =
|
|
612
|
+
borrow(Type, instanceKey = DEFAULT_STRUCTURAL_KEY) {
|
|
722
613
|
return this.acquire(Type, instanceKey, {
|
|
723
614
|
canCreate: false,
|
|
724
615
|
countRef: false
|
|
@@ -733,7 +624,7 @@ var StateContainerRegistry = class {
|
|
|
733
624
|
* @param instanceKey - Pre-resolved instance key (defaults to 'default')
|
|
734
625
|
* @returns Discriminated union with either the instance or an error
|
|
735
626
|
*/
|
|
736
|
-
borrowSafe(Type, instanceKey =
|
|
627
|
+
borrowSafe(Type, instanceKey = DEFAULT_STRUCTURAL_KEY) {
|
|
737
628
|
try {
|
|
738
629
|
return {
|
|
739
630
|
error: null,
|
|
@@ -779,7 +670,7 @@ var StateContainerRegistry = class {
|
|
|
779
670
|
* @param forceDispose - Force immediate disposal regardless of refs
|
|
780
671
|
* @param refId - The specific ref to remove; removes one arbitrary ref if omitted
|
|
781
672
|
*/
|
|
782
|
-
release(Type, instanceKey =
|
|
673
|
+
release(Type, instanceKey = DEFAULT_STRUCTURAL_KEY, forceDispose = false, refId) {
|
|
783
674
|
const instances = this.ensureInstancesMap(Type);
|
|
784
675
|
const entry = instances.get(instanceKey);
|
|
785
676
|
if (!entry) return;
|
|
@@ -804,20 +695,12 @@ var StateContainerRegistry = class {
|
|
|
804
695
|
}
|
|
805
696
|
}
|
|
806
697
|
if (releasedRefId) this.emit("refReleased", entry.instance, releasedRefId);
|
|
807
|
-
|
|
808
|
-
if (entry.refs.size === 0 && !keepAlive) {
|
|
809
|
-
const deps = entry.instance.$blac.dependencies;
|
|
698
|
+
if (this._isUnowned(Type, entry)) {
|
|
810
699
|
if (!entry.instance.$blac.disposed) entry.instance.dispose();
|
|
811
700
|
instances.delete(instanceKey);
|
|
812
|
-
|
|
813
|
-
const depInstances = this.ensureInstancesMap(DepType);
|
|
814
|
-
const depEntry = depInstances.get(depKey);
|
|
815
|
-
if (depEntry && depEntry.refs.size === 0 && !isKeepAliveClass(DepType) && !depEntry.instance.$blac.disposed) {
|
|
816
|
-
depEntry.instance.dispose();
|
|
817
|
-
depInstances.delete(depKey);
|
|
818
|
-
}
|
|
819
|
-
}
|
|
701
|
+
return;
|
|
820
702
|
}
|
|
703
|
+
this._syncActivation(entry);
|
|
821
704
|
}
|
|
822
705
|
/**
|
|
823
706
|
* Get all instances of a specific type.
|
|
@@ -827,7 +710,7 @@ var StateContainerRegistry = class {
|
|
|
827
710
|
getAll(Type) {
|
|
828
711
|
const instances = this.ensureInstancesMap(Type);
|
|
829
712
|
const result = [];
|
|
830
|
-
for (const entry of instances.values()) result.push(entry.instance);
|
|
713
|
+
for (const entry of instances.values()) if (!entry.instance.$blac.disposed) result.push(entry.instance);
|
|
831
714
|
return result;
|
|
832
715
|
}
|
|
833
716
|
/**
|
|
@@ -864,7 +747,7 @@ var StateContainerRegistry = class {
|
|
|
864
747
|
* @param instanceKey - Pre-resolved instance key (defaults to 'default')
|
|
865
748
|
* @returns Current ref count (0 if instance doesn't exist)
|
|
866
749
|
*/
|
|
867
|
-
getRefCount(Type, instanceKey =
|
|
750
|
+
getRefCount(Type, instanceKey = DEFAULT_STRUCTURAL_KEY) {
|
|
868
751
|
return this.ensureInstancesMap(Type).get(instanceKey)?.refs.size ?? 0;
|
|
869
752
|
}
|
|
870
753
|
/**
|
|
@@ -875,13 +758,23 @@ var StateContainerRegistry = class {
|
|
|
875
758
|
* @param instanceKey - Pre-resolved instance key (defaults to 'default')
|
|
876
759
|
* @returns Array of ref ID strings (empty if instance doesn't exist)
|
|
877
760
|
*/
|
|
878
|
-
getRefIds(Type, instanceKey =
|
|
761
|
+
getRefIds(Type, instanceKey = DEFAULT_STRUCTURAL_KEY) {
|
|
879
762
|
const instances = this.instancesByConstructor.get(Type);
|
|
880
763
|
if (!instances) return [];
|
|
881
764
|
const entry = instances.get(instanceKey);
|
|
882
765
|
return entry ? Array.from(entry.refs.keys()) : [];
|
|
883
766
|
}
|
|
884
767
|
/**
|
|
768
|
+
* Get all active reference IDs for an instance by its `$blac.id`, without
|
|
769
|
+
* needing the owning Type. Used by `PluginContext.getRefIds`.
|
|
770
|
+
* @param instanceId - The instance's `$blac.id`
|
|
771
|
+
* @returns Array of ref ID strings (empty if instance doesn't exist)
|
|
772
|
+
*/
|
|
773
|
+
getRefIdsById(instanceId) {
|
|
774
|
+
const entry = this._entryById.get(instanceId);
|
|
775
|
+
return entry ? Array.from(entry.refs.keys()) : [];
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
885
778
|
* Check if an instance exists.
|
|
886
779
|
*
|
|
887
780
|
* @internal Internal key tier; public callers use the args-based `hasInstance`.
|
|
@@ -889,7 +782,7 @@ var StateContainerRegistry = class {
|
|
|
889
782
|
* @param instanceKey - Pre-resolved instance key (defaults to 'default')
|
|
890
783
|
* @returns true if instance exists
|
|
891
784
|
*/
|
|
892
|
-
hasInstance(Type, instanceKey =
|
|
785
|
+
hasInstance(Type, instanceKey = DEFAULT_STRUCTURAL_KEY) {
|
|
893
786
|
return this.ensureInstancesMap(Type).has(instanceKey);
|
|
894
787
|
}
|
|
895
788
|
/**
|
|
@@ -901,7 +794,6 @@ var StateContainerRegistry = class {
|
|
|
901
794
|
clearAll() {
|
|
902
795
|
for (const Type of this.types) this.clear(Type);
|
|
903
796
|
this.types.clear();
|
|
904
|
-
this.registeredTypeNames.clear();
|
|
905
797
|
}
|
|
906
798
|
/**
|
|
907
799
|
* Get registry statistics for debugging.
|
|
@@ -936,9 +828,11 @@ var StateContainerRegistry = class {
|
|
|
936
828
|
* @returns Unsubscribe function
|
|
937
829
|
*/
|
|
938
830
|
on(event, listener) {
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
831
|
+
let instance = this.listeners.get(event);
|
|
832
|
+
if (!instance) {
|
|
833
|
+
instance = /* @__PURE__ */ new Set();
|
|
834
|
+
this.listeners.set(event, instance);
|
|
835
|
+
}
|
|
942
836
|
instance.add(listener);
|
|
943
837
|
if (event === "stateChanged") this._stateChangedListenerCount++;
|
|
944
838
|
return () => {
|
|
@@ -971,6 +865,15 @@ var StateContainerRegistry = class {
|
|
|
971
865
|
newState
|
|
972
866
|
]);
|
|
973
867
|
}
|
|
868
|
+
/**
|
|
869
|
+
* Deliver one event per emit, in order — deliberately NOT coalesced.
|
|
870
|
+
*
|
|
871
|
+
* This is a transition log: devtools, time-travel debugging and perf
|
|
872
|
+
* monitoring need every intermediate `prev`/`next`, which coalescing would
|
|
873
|
+
* destroy. The plugin `onStateChange` bridge is the coalesced, `PathSet`-
|
|
874
|
+
* carrying lane (see `PluginManager.setupLifecycleHooks`); the two differ on
|
|
875
|
+
* purpose, so a listener picks the lane that matches what it needs.
|
|
876
|
+
*/
|
|
974
877
|
flushStateChanged() {
|
|
975
878
|
const pending = this._pendingStateChanges;
|
|
976
879
|
this._pendingStateChanges = null;
|
|
@@ -980,20 +883,10 @@ var StateContainerRegistry = class {
|
|
|
980
883
|
};
|
|
981
884
|
/**
|
|
982
885
|
* Global default registry instance
|
|
886
|
+
* @public
|
|
983
887
|
*/
|
|
984
888
|
const globalRegistry = new StateContainerRegistry();
|
|
985
|
-
/**
|
|
986
|
-
* Global plugin manager (initialized lazily)
|
|
987
|
-
*/
|
|
988
|
-
let _globalPluginManager = null;
|
|
989
|
-
/**
|
|
990
|
-
* Get the global plugin manager
|
|
991
|
-
*/
|
|
992
|
-
function getPluginManager() {
|
|
993
|
-
if (!_globalPluginManager) _globalPluginManager = createPluginManager(globalRegistry);
|
|
994
|
-
return _globalPluginManager;
|
|
995
|
-
}
|
|
996
889
|
//#endregion
|
|
997
|
-
export {
|
|
890
|
+
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 };
|
|
998
891
|
|
|
999
|
-
//# sourceMappingURL=StateContainerRegistry-
|
|
892
|
+
//# sourceMappingURL=StateContainerRegistry-BH7aOMWV.js.map
|