@blac/core 2.0.20 → 2.0.22
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/{StateContainerRegistry-CSNm2Ws5.cjs → StateContainerRegistry-141uHhtF.cjs} +300 -397
- package/dist/StateContainerRegistry-141uHhtF.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-Dj77cok9.js → StateContainerRegistry-BsH_s0pJ.js} +303 -413
- package/dist/StateContainerRegistry-BsH_s0pJ.js.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-D9BIRjwv.cjs → StateContainerRegistry-MkT0W4C2.cjs} +322 -411
- package/dist/StateContainerRegistry-MkT0W4C2.cjs.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 +2 -2
- package/dist/config.d.ts +2 -2
- package/dist/constants.d.cts +4 -20
- package/dist/constants.d.ts +4 -20
- package/dist/core/Cubit.d.ts +14 -10
- package/dist/core/StateContainer.d.ts +68 -8
- package/dist/core/StateContainerRegistry.d.ts +100 -19
- package/dist/core/meta.d.ts +34 -47
- package/dist/core/symbols.d.ts +18 -1
- package/dist/decorators/blac.d.ts +28 -26
- package/dist/{ensure-BKdq5xsY.cjs → ensure-BjhbDW8Z.cjs} +223 -40
- package/dist/ensure-BjhbDW8Z.cjs.map +1 -0
- package/dist/ensure-BnVyd6s4.js +730 -0
- package/dist/ensure-BnVyd6s4.js.map +1 -0
- package/dist/ensure-CneMkpbI.js +731 -0
- package/dist/ensure-CneMkpbI.js.map +1 -0
- package/dist/{ensure-CQimeD0I.cjs → ensure-D15vGnk5.cjs} +348 -124
- package/dist/ensure-D15vGnk5.cjs.map +1 -0
- package/dist/{ensure-B1dEDsZV.cjs → ensure-D3w6YGp9.cjs} +349 -124
- package/dist/ensure-D3w6YGp9.cjs.map +1 -0
- package/dist/{ensure-B2DYCbbI.cjs → ensure-ORVw-WRE.cjs} +214 -39
- package/dist/ensure-ORVw-WRE.cjs.map +1 -0
- package/dist/{ensure-B59ri8oo.js → ensure-dsqWhIuO.js} +192 -39
- package/dist/ensure-dsqWhIuO.js.map +1 -0
- package/dist/{ensure-BSJHkUNX.js → ensure-k-6q7O25.js} +183 -38
- package/dist/ensure-k-6q7O25.js.map +1 -0
- package/dist/index.cjs +212 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -6
- package/dist/index.d.ts +4 -6
- package/dist/index.js +192 -12
- package/dist/index.js.map +1 -1
- package/dist/plugin/BlacPlugin.d.ts +14 -0
- package/dist/plugin/PluginManager.d.ts +21 -11
- package/dist/plugins.cjs +403 -3
- package/dist/plugins.cjs.map +1 -0
- package/dist/plugins.d.cts +6 -2
- package/dist/plugins.d.ts +6 -2
- package/dist/plugins.js +401 -1
- package/dist/plugins.js.map +1 -0
- package/dist/registry/acquire.d.ts +2 -2
- package/dist/registry/config.d.ts +9 -0
- package/dist/registry/management.d.ts +3 -0
- package/dist/registry/queries.d.ts +15 -0
- package/dist/registry/release.d.ts +3 -3
- package/dist/testing.cjs +13 -15
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +2 -4
- package/dist/testing.js.map +1 -1
- package/dist/types/branded.d.ts +3 -3
- package/dist/types/utilities.d.ts +45 -18
- package/dist/utils/static-props.d.ts +25 -1
- package/dist/utils/structural-key.d.ts +0 -7
- package/dist/watch/index.d.ts +1 -1
- package/dist/watch/watch.d.ts +22 -3
- package/package.json +16 -55
- 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-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-DVIBTxGZ.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-lIwo-0m3.cjs.map +0 -1
- package/dist/acquire-B1LYXSGj.js +0 -35
- package/dist/acquire-B1LYXSGj.js.map +0 -1
- package/dist/acquire-B1Wuqla6.cjs +0 -46
- package/dist/acquire-B1Wuqla6.cjs.map +0 -1
- package/dist/acquire-BJ3xUEmh.cjs +0 -46
- package/dist/acquire-BJ3xUEmh.cjs.map +0 -1
- package/dist/acquire-BP-ZfUH2.js +0 -35
- package/dist/acquire-BP-ZfUH2.js.map +0 -1
- package/dist/acquire-BRIJVJaA.js +0 -35
- package/dist/acquire-BRIJVJaA.js.map +0 -1
- package/dist/acquire-BZIs6tpN.cjs +0 -46
- package/dist/acquire-BZIs6tpN.cjs.map +0 -1
- package/dist/acquire-B_p1fNEh.cjs +0 -46
- package/dist/acquire-B_p1fNEh.cjs.map +0 -1
- package/dist/acquire-BdsVZBSe.js +0 -35
- 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-CbMz7gWs.cjs +0 -46
- package/dist/acquire-CbMz7gWs.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-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-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-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-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-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-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.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-vxAGa2v3.js +0 -536
- package/dist/ensure-vxAGa2v3.js.map +0 -1
- 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-AFuqQEwz.js +0 -38
- package/dist/management-AFuqQEwz.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-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-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-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-BHfCtbn1.cjs +0 -119
- package/dist/watch-BHfCtbn1.cjs.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-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/testing.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { r as setRegistry, t as getRegistry } from "./config-DXI3kzmA.js";
|
|
4
|
-
import { n as resolveInstanceKey } from "./acquire-B1LYXSGj.js";
|
|
1
|
+
import { i as INIT_CONFIG, r as APPLY_DEPS, t as StateContainerRegistry } from "./StateContainerRegistry-BsH_s0pJ.js";
|
|
2
|
+
import { i as Cubit, l as setRegistry, r as resolveInstanceKey, s as getRegistry, t as ensure } from "./ensure-CneMkpbI.js";
|
|
5
3
|
//#region src/testing.ts
|
|
6
4
|
/** Synthetic owner id used by test helpers for pre-wired deps. */
|
|
7
5
|
const TESTING_DEPS_OWNER = "testing-deps";
|
package/dist/testing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.js","names":[],"sources":["../src/testing.ts"],"sourcesContent":["import { Cubit } from './core/Cubit';\nimport { StateContainerRegistry } from './core/StateContainerRegistry';\nimport { APPLY_DEPS, INIT_CONFIG } from './core/symbols';\nimport { ensure, getRegistry, setRegistry } from './registry';\nimport { resolveInstanceKey } from './registry/acquire';\nimport type {\n ExtractArgs,\n ExtractDeps,\n ExtractState,\n StateContainerConstructor,\n} from './types/utilities';\n\n/** Synthetic owner id used by test helpers for pre-wired deps. */\nconst TESTING_DEPS_OWNER = 'testing-deps';\n\ndeclare const beforeEach: (fn: () => void) => void;\ndeclare const afterEach: (fn: () => void) => void;\n\n// --- createTestRegistry + withTestRegistry ---\n\nexport function createTestRegistry(): StateContainerRegistry {\n return new StateContainerRegistry();\n}\n\nexport function withTestRegistry<T>(\n fn: (registry: StateContainerRegistry) => T,\n): T {\n const previous = getRegistry();\n const testRegistry = createTestRegistry();\n setRegistry(testRegistry);\n try {\n const result = fn(testRegistry);\n if (result instanceof Promise) {\n return result.then(\n (value) => {\n setRegistry(previous);\n return value;\n },\n (error) => {\n setRegistry(previous);\n throw error;\n },\n ) as T;\n }\n setRegistry(previous);\n return result;\n } catch (error) {\n setRegistry(previous);\n throw error;\n }\n}\n\n// --- blacTestSetup ---\n\nexport function blacTestSetup(): void {\n let savedRegistry: StateContainerRegistry;\n beforeEach(() => {\n savedRegistry = getRegistry();\n setRegistry(new StateContainerRegistry());\n });\n afterEach(() => {\n setRegistry(savedRegistry);\n });\n}\n\n// --- registerOverride + overrideEnsure ---\n\nexport function registerOverride<T extends StateContainerConstructor>(\n BlocClass: T,\n instance: InstanceType<T>,\n args?: ExtractArgs<T>,\n): void {\n const registry = getRegistry();\n const key = resolveInstanceKey(BlocClass, args);\n registry.insertInstance(\n BlocClass,\n key,\n instance,\n new Map([['testing-override', 1]]),\n );\n}\n\nexport function overrideEnsure<T extends StateContainerConstructor, R>(\n BlocClass: T,\n instance: InstanceType<T>,\n fn: () => R,\n args?: ExtractArgs<T>,\n): R {\n return withTestRegistry(() => {\n registerOverride(BlocClass, instance, args);\n return fn();\n });\n}\n\n// --- createCubitStub ---\n\ntype MethodKeys<T> = {\n [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;\n}[keyof T];\n\nexport interface CubitStubOptions<T extends StateContainerConstructor> {\n state?: ExtractState<T> extends Record<string, any>\n ? Partial<ExtractState<T>>\n : ExtractState<T>;\n methods?: Partial<\n Record<MethodKeys<InstanceType<T>>, (...args: any[]) => any>\n >;\n /**\n * Args to pass to init(). If the bloc's Args type is not void, supplying\n * args here causes initConfig({ args }) to be called so init() runs.\n */\n args?: ExtractArgs<T> extends void ? never : ExtractArgs<T>;\n /**\n * Deps slice to pre-wire via the core [APPLY_DEPS] path (synthetic owner\n * \"testing-deps\"), so onDepsChanged fires during tests.\n */\n deps?: Partial<ExtractDeps<T>>;\n}\n\nexport function createCubitStub<T extends StateContainerConstructor>(\n BlocClass: T,\n options?: CubitStubOptions<T>,\n): InstanceType<T> {\n const instance = new BlocClass() as InstanceType<T>;\n\n // Run init() if args are supplied — goes through the same initConfig path\n // that the registry uses, so lifecycle hooks fire correctly.\n if (options?.args != null) {\n instance[INIT_CONFIG]({ args: options.args });\n }\n\n if (options?.state != null) {\n if (instance instanceof Cubit) {\n const currentState = instance.state;\n if (\n typeof currentState === 'object' &&\n currentState !== null &&\n typeof options.state === 'object' &&\n options.state !== null\n ) {\n instance.patch(options.state as any);\n } else {\n instance.emit(options.state as any);\n }\n }\n }\n if (options?.methods) {\n for (const [key, impl] of Object.entries(options.methods)) {\n if (typeof impl === 'function') {\n (instance as any)[key] = impl;\n }\n }\n }\n\n // Pre-wire deps via the core merge path so onDepsChanged fires in tests.\n if (options?.deps != null) {\n (instance as any)[APPLY_DEPS](TESTING_DEPS_OWNER, options.deps);\n }\n\n return instance;\n}\n\n// --- withBlocState ---\n\nexport function withBlocState<T extends StateContainerConstructor>(\n BlocClass: T,\n state: ExtractState<T> extends Record<string, any>\n ? Partial<ExtractState<T>>\n : ExtractState<T>,\n args?: ExtractArgs<T>,\n): InstanceType<T> {\n const instance = ensure(BlocClass, { args });\n if (instance instanceof Cubit) {\n const currentState = instance.state;\n if (\n typeof currentState === 'object' &&\n currentState !== null &&\n typeof state === 'object' &&\n state !== null\n ) {\n instance.patch(state as any);\n } else {\n instance.emit(state as any);\n }\n }\n return instance;\n}\n\n// --- withBlocMethod ---\n\nexport function withBlocMethod<T extends StateContainerConstructor>(\n BlocClass: T,\n methodName: keyof InstanceType<T>,\n impl: (...args: any[]) => any,\n args?: ExtractArgs<T>,\n): InstanceType<T> {\n const instance = ensure(BlocClass, { args });\n (instance as any)[methodName] = impl;\n return instance;\n}\n\n// --- flush ---\n\n/**\n * Drain pending microtasks so any channel-flushed effects (channel\n * subscribers, `onSystemEvent('stateChanged')` handlers, plugin hooks) run\n * before the next assertion.\n *\n * The default `MicrotaskScheduler` coalesces emits within a tick; tests\n * that emit and then assert on subscriber side-effects need `await flush()`\n * between the two.\n */\nexport async function flush(): Promise<void> {\n // queueMicrotask wins the race against the channel's own queued flush —\n // we resolve after the channel has drained its current pending flush.\n await Promise.resolve();\n await Promise.resolve();\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"testing.js","names":[],"sources":["../src/testing.ts"],"sourcesContent":["import { Cubit } from './core/Cubit';\nimport { StateContainerRegistry } from './core/StateContainerRegistry';\nimport { APPLY_DEPS, INIT_CONFIG } from './core/symbols';\nimport { ensure, getRegistry, setRegistry } from './registry';\nimport { resolveInstanceKey } from './registry/acquire';\nimport type {\n ExtractArgs,\n ExtractDeps,\n ExtractState,\n StateContainerConstructor,\n} from './types/utilities';\n\n/** Synthetic owner id used by test helpers for pre-wired deps. */\nconst TESTING_DEPS_OWNER = 'testing-deps';\n\ndeclare const beforeEach: (fn: () => void) => void;\ndeclare const afterEach: (fn: () => void) => void;\n\n// --- createTestRegistry + withTestRegistry ---\n\nexport function createTestRegistry(): StateContainerRegistry {\n return new StateContainerRegistry();\n}\n\nexport function withTestRegistry<T>(\n fn: (registry: StateContainerRegistry) => T,\n): T {\n const previous = getRegistry();\n const testRegistry = createTestRegistry();\n setRegistry(testRegistry);\n try {\n const result = fn(testRegistry);\n if (result instanceof Promise) {\n return result.then(\n (value) => {\n setRegistry(previous);\n return value;\n },\n (error) => {\n setRegistry(previous);\n throw error;\n },\n ) as T;\n }\n setRegistry(previous);\n return result;\n } catch (error) {\n setRegistry(previous);\n throw error;\n }\n}\n\n// --- blacTestSetup ---\n\nexport function blacTestSetup(): void {\n let savedRegistry: StateContainerRegistry;\n beforeEach(() => {\n savedRegistry = getRegistry();\n setRegistry(new StateContainerRegistry());\n });\n afterEach(() => {\n setRegistry(savedRegistry);\n });\n}\n\n// --- registerOverride + overrideEnsure ---\n\nexport function registerOverride<T extends StateContainerConstructor>(\n BlocClass: T,\n instance: InstanceType<T>,\n args?: ExtractArgs<T>,\n): void {\n const registry = getRegistry();\n const key = resolveInstanceKey(BlocClass, args);\n registry.insertInstance(\n BlocClass,\n key,\n instance,\n new Map([['testing-override', 1]]),\n );\n}\n\nexport function overrideEnsure<T extends StateContainerConstructor, R>(\n BlocClass: T,\n instance: InstanceType<T>,\n fn: () => R,\n args?: ExtractArgs<T>,\n): R {\n return withTestRegistry(() => {\n registerOverride(BlocClass, instance, args);\n return fn();\n });\n}\n\n// --- createCubitStub ---\n\ntype MethodKeys<T> = {\n [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;\n}[keyof T];\n\nexport interface CubitStubOptions<T extends StateContainerConstructor> {\n state?: ExtractState<T> extends Record<string, any>\n ? Partial<ExtractState<T>>\n : ExtractState<T>;\n methods?: Partial<\n Record<MethodKeys<InstanceType<T>>, (...args: any[]) => any>\n >;\n /**\n * Args to pass to init(). If the bloc's Args type is not void, supplying\n * args here causes `initConfig({ args })` to be called so `init()` runs.\n */\n args?: ExtractArgs<T> extends void ? never : ExtractArgs<T>;\n /**\n * Deps slice to pre-wire via the core [APPLY_DEPS] path (synthetic owner\n * \"testing-deps\"), so onDepsChanged fires during tests.\n */\n deps?: Partial<ExtractDeps<T>>;\n}\n\nexport function createCubitStub<T extends StateContainerConstructor>(\n BlocClass: T,\n options?: CubitStubOptions<T>,\n): InstanceType<T> {\n const instance = new BlocClass() as InstanceType<T>;\n\n // Run init() if args are supplied — goes through the same initConfig path\n // that the registry uses, so lifecycle hooks fire correctly.\n if (options?.args != null) {\n instance[INIT_CONFIG]({ args: options.args });\n }\n\n if (options?.state != null) {\n if (instance instanceof Cubit) {\n const currentState = instance.state;\n if (\n typeof currentState === 'object' &&\n currentState !== null &&\n typeof options.state === 'object' &&\n options.state !== null\n ) {\n instance.patch(options.state as any);\n } else {\n instance.emit(options.state as any);\n }\n }\n }\n if (options?.methods) {\n for (const [key, impl] of Object.entries(options.methods)) {\n if (typeof impl === 'function') {\n (instance as any)[key] = impl;\n }\n }\n }\n\n // Pre-wire deps via the core merge path so onDepsChanged fires in tests.\n if (options?.deps != null) {\n (instance as any)[APPLY_DEPS](TESTING_DEPS_OWNER, options.deps);\n }\n\n return instance;\n}\n\n// --- withBlocState ---\n\nexport function withBlocState<T extends StateContainerConstructor>(\n BlocClass: T,\n state: ExtractState<T> extends Record<string, any>\n ? Partial<ExtractState<T>>\n : ExtractState<T>,\n args?: ExtractArgs<T>,\n): InstanceType<T> {\n const instance = ensure(BlocClass, { args });\n if (instance instanceof Cubit) {\n const currentState = instance.state;\n if (\n typeof currentState === 'object' &&\n currentState !== null &&\n typeof state === 'object' &&\n state !== null\n ) {\n instance.patch(state as any);\n } else {\n instance.emit(state as any);\n }\n }\n return instance;\n}\n\n// --- withBlocMethod ---\n\nexport function withBlocMethod<T extends StateContainerConstructor>(\n BlocClass: T,\n methodName: keyof InstanceType<T>,\n impl: (...args: any[]) => any,\n args?: ExtractArgs<T>,\n): InstanceType<T> {\n const instance = ensure(BlocClass, { args });\n (instance as any)[methodName] = impl;\n return instance;\n}\n\n// --- flush ---\n\n/**\n * Drain pending microtasks so any channel-flushed effects (channel\n * subscribers, `onSystemEvent('stateChanged')` handlers, plugin hooks) run\n * before the next assertion.\n *\n * The default `MicrotaskScheduler` coalesces emits within a tick; tests\n * that emit and then assert on subscriber side-effects need `await flush()`\n * between the two.\n */\nexport async function flush(): Promise<void> {\n // queueMicrotask wins the race against the channel's own queued flush —\n // we resolve after the channel has drained its current pending flush.\n await Promise.resolve();\n await Promise.resolve();\n}\n"],"mappings":";;;;AAaA,MAAM,qBAAqB;AAO3B,SAAgB,qBAA6C;CAC3D,OAAO,IAAI,uBAAuB;AACpC;AAEA,SAAgB,iBACd,IACG;CACH,MAAM,WAAW,YAAY;CAC7B,MAAM,eAAe,mBAAmB;CACxC,YAAY,YAAY;CACxB,IAAI;EACF,MAAM,SAAS,GAAG,YAAY;EAC9B,IAAI,kBAAkB,SACpB,OAAO,OAAO,MACX,UAAU;GACT,YAAY,QAAQ;GACpB,OAAO;EACT,IACC,UAAU;GACT,YAAY,QAAQ;GACpB,MAAM;EACR,CACF;EAEF,YAAY,QAAQ;EACpB,OAAO;CACT,SAAS,OAAO;EACd,YAAY,QAAQ;EACpB,MAAM;CACR;AACF;AAIA,SAAgB,gBAAsB;CACpC,IAAI;CACJ,iBAAiB;EACf,gBAAgB,YAAY;EAC5B,YAAY,IAAI,uBAAuB,CAAC;CAC1C,CAAC;CACD,gBAAgB;EACd,YAAY,aAAa;CAC3B,CAAC;AACH;AAIA,SAAgB,iBACd,WACA,UACA,MACM;CACN,MAAM,WAAW,YAAY;CAC7B,MAAM,MAAM,mBAAmB,WAAW,IAAI;CAC9C,SAAS,eACP,WACA,KACA,UACA,IAAI,IAAI,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CACnC;AACF;AAEA,SAAgB,eACd,WACA,UACA,IACA,MACG;CACH,OAAO,uBAAuB;EAC5B,iBAAiB,WAAW,UAAU,IAAI;EAC1C,OAAO,GAAG;CACZ,CAAC;AACH;AA2BA,SAAgB,gBACd,WACA,SACiB;CACjB,MAAM,WAAW,IAAI,UAAU;CAI/B,IAAI,SAAS,QAAQ,MACnB,SAAS,aAAa,EAAE,MAAM,QAAQ,KAAK,CAAC;CAG9C,IAAI,SAAS,SAAS;MAChB,oBAAoB,OAAO;GAC7B,MAAM,eAAe,SAAS;GAC9B,IACE,OAAO,iBAAiB,YACxB,iBAAiB,QACjB,OAAO,QAAQ,UAAU,YACzB,QAAQ,UAAU,MAElB,SAAS,MAAM,QAAQ,KAAY;QAEnC,SAAS,KAAK,QAAQ,KAAY;EAEtC;;CAEF,IAAI,SAAS;OACN,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,QAAQ,OAAO,GACtD,IAAI,OAAO,SAAS,YAClB,SAAkB,OAAO;CAAA;CAM/B,IAAI,SAAS,QAAQ,MACnB,SAAkB,YAAY,oBAAoB,QAAQ,IAAI;CAGhE,OAAO;AACT;AAIA,SAAgB,cACd,WACA,OAGA,MACiB;CACjB,MAAM,WAAW,OAAO,WAAW,EAAE,KAAK,CAAC;CAC3C,IAAI,oBAAoB,OAAO;EAC7B,MAAM,eAAe,SAAS;EAC9B,IACE,OAAO,iBAAiB,YACxB,iBAAiB,QACjB,OAAO,UAAU,YACjB,UAAU,MAEV,SAAS,MAAM,KAAY;OAE3B,SAAS,KAAK,KAAY;CAE9B;CACA,OAAO;AACT;AAIA,SAAgB,eACd,WACA,YACA,MACA,MACiB;CACjB,MAAM,WAAW,OAAO,WAAW,EAAE,KAAK,CAAC;CAC3C,SAAkB,cAAc;CAChC,OAAO;AACT;;;;;;;;;;AAaA,eAAsB,QAAuB;CAG3C,MAAM,QAAQ,QAAQ;CACtB,MAAM,QAAQ,QAAQ;AACxB"}
|
package/dist/types/branded.d.ts
CHANGED
|
@@ -2,15 +2,15 @@ declare const brand: unique symbol;
|
|
|
2
2
|
/**
|
|
3
3
|
* Utility type for creating branded/nominal types.
|
|
4
4
|
* Prevents accidental type confusion between similar primitive types.
|
|
5
|
-
* @
|
|
6
|
-
* @
|
|
5
|
+
* @typeParam T - The base type
|
|
6
|
+
* @typeParam B - The brand identifier
|
|
7
7
|
*/
|
|
8
8
|
export type Brand<T, B> = T & {
|
|
9
9
|
[brand]: B;
|
|
10
10
|
};
|
|
11
11
|
/**
|
|
12
12
|
* Branded string type for type-safe IDs.
|
|
13
|
-
* @
|
|
13
|
+
* @typeParam B - The brand identifier
|
|
14
14
|
*/
|
|
15
15
|
export type BrandedId<B> = Brand<string, B>;
|
|
16
16
|
/**
|
|
@@ -1,50 +1,77 @@
|
|
|
1
1
|
import type { StateContainer } from '../core/StateContainer';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Recursively mark all properties readonly. The mirror of
|
|
4
|
+
* `DeepPartial` in `@dirtytalk/structural`, and carves out the same
|
|
5
|
+
* built-ins for the same reason.
|
|
6
|
+
*
|
|
7
|
+
* - Arrays become `ReadonlyArray`, recursing into the element type.
|
|
8
|
+
* - `Map`/`Set` become their `Readonly` counterparts so their contents are
|
|
9
|
+
* frozen too, rather than only the binding.
|
|
10
|
+
* - `Date | RegExp` are kept as-is; mapping over them would freeze their
|
|
11
|
+
* prototype methods instead of their (inaccessible) internal state.
|
|
12
|
+
* - Primitives and functions pass through unchanged.
|
|
13
|
+
*
|
|
14
|
+
* @typeParam T - The type to deeply freeze
|
|
15
|
+
* @public
|
|
5
16
|
*/
|
|
6
|
-
export type
|
|
17
|
+
export type DeepReadonly<T> = T extends (...args: any[]) => any ? T : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepReadonly<U>> : T extends ReadonlyMap<infer K, infer V> ? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>> : T extends ReadonlySet<infer U> ? ReadonlySet<DeepReadonly<U>> : T extends Date | RegExp ? T : T extends object ? {
|
|
18
|
+
readonly [K in keyof T]: DeepReadonly<T[K]>;
|
|
19
|
+
} : T;
|
|
20
|
+
/**
|
|
21
|
+
* Extract the state type from a StateContainer, deeply readonly.
|
|
22
|
+
*
|
|
23
|
+
* State is owned by the container: consumers read it and mutate only through
|
|
24
|
+
* `emit`/`patch`, so nested writes are a compile error rather than a silent
|
|
25
|
+
* desync from the change-tracking channel.
|
|
26
|
+
*
|
|
27
|
+
* @typeParam T - The StateContainer type
|
|
28
|
+
*/
|
|
29
|
+
export type ExtractState<T> = T extends StateContainerConstructor<infer S> ? DeepReadonly<S> : never;
|
|
7
30
|
export type ExtractStateMutable<T> = T extends StateContainerConstructor<infer S> ? S : never;
|
|
8
31
|
/**
|
|
9
32
|
* Constructor type for StateContainer classes
|
|
10
|
-
* @
|
|
33
|
+
* @typeParam S - State type managed by the container
|
|
11
34
|
*/
|
|
12
|
-
export type StateContainerConstructor<S extends object = any> = new (
|
|
35
|
+
export type StateContainerConstructor<S extends object = any> = new () => StateContainer<S, any, any>;
|
|
13
36
|
/**
|
|
14
37
|
* Extract the args type (serializable construction/identity data) from a
|
|
15
38
|
* StateContainer subclass.
|
|
16
|
-
* @
|
|
39
|
+
* @typeParam T - The StateContainer constructor type
|
|
17
40
|
*/
|
|
18
41
|
export type ExtractArgs<T> = T extends new () => StateContainer<any, infer A, any> ? A : void;
|
|
19
42
|
/**
|
|
20
43
|
* Extract the deps type (injected non-serializable handles) from a
|
|
21
44
|
* StateContainer subclass.
|
|
22
|
-
* @
|
|
45
|
+
* @typeParam T - The StateContainer constructor type
|
|
23
46
|
*/
|
|
24
47
|
export type ExtractDeps<T> = T extends new () => StateContainer<any, any, infer D> ? D : Record<string, never>;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Narrow a container instance's `state` without erasing the class. A plain
|
|
50
|
+
* intersection keeps private members, `this` types and symbol keys, so the
|
|
51
|
+
* result stays assignable to `StateContainer`; `state` is getter-only at the
|
|
52
|
+
* source, so no `readonly` modifier is needed here.
|
|
53
|
+
* @public
|
|
54
|
+
*/
|
|
55
|
+
export type WithState<I, S> = I & {
|
|
56
|
+
state: S;
|
|
33
57
|
};
|
|
58
|
+
export type InstanceReadonlyState<T extends StateContainerConstructor = StateContainerConstructor> = WithState<InstanceType<T>, ExtractState<T>>;
|
|
59
|
+
export type InstanceState<T extends StateContainerConstructor = StateContainerConstructor> = WithState<InstanceType<T>, ExtractStateMutable<T>>;
|
|
60
|
+
export type StateContainerInstance<S extends object = any> = WithState<StateContainer<S, any, any>, Readonly<S>>;
|
|
34
61
|
/**
|
|
35
62
|
* Extract constructor argument types from a class
|
|
36
|
-
* @
|
|
63
|
+
* @typeParam T - The class type
|
|
37
64
|
*/
|
|
38
65
|
export type ExtractConstructorArgs<T> = T extends new (...args: infer P) => any ? P : never[];
|
|
39
66
|
/**
|
|
40
67
|
* Extract instance type from an abstract class constructor
|
|
41
|
-
* @
|
|
68
|
+
* @typeParam T - The abstract class constructor type
|
|
42
69
|
*/
|
|
43
70
|
export type BlocInstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;
|
|
44
71
|
/**
|
|
45
72
|
* Constructor type for StateContainer classes.
|
|
46
73
|
* Used for type-safe hook parameters.
|
|
47
|
-
* @
|
|
74
|
+
* @typeParam TBloc - The StateContainer instance type
|
|
48
75
|
*/
|
|
49
76
|
export type BlocConstructor<S extends object = any, T extends new (...args: any[]) => StateContainer<S, any, any> = new (...args: any[]) => StateContainer<S, any, any>> = (new (...args: any[]) => InstanceType<T>) & {
|
|
50
77
|
keepAlive?: boolean;
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
import type { EqualityFn } from '../config';
|
|
5
5
|
import { StateContainerConstructor } from '../types/utilities';
|
|
6
6
|
/**
|
|
7
|
-
* Get a static property from a class constructor
|
|
7
|
+
* Get a static property from a class constructor, walking the prototype
|
|
8
|
+
* chain so subclasses inherit the value unless they define their own.
|
|
8
9
|
* Type-safe helper that avoids (Type as any) casts
|
|
9
10
|
*
|
|
10
11
|
* @param Type - The class constructor
|
|
@@ -13,9 +14,19 @@ import { StateContainerConstructor } from '../types/utilities';
|
|
|
13
14
|
* @returns The property value or default
|
|
14
15
|
*/
|
|
15
16
|
export declare function getStaticProp<V, T extends StateContainerConstructor = StateContainerConstructor>(Type: T, propName: string, defaultValue?: V): V | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Get a static property declared directly on `Type`, ignoring the prototype
|
|
19
|
+
* chain, so subclasses never inherit a base class's value.
|
|
20
|
+
*
|
|
21
|
+
* @param Type - The class constructor
|
|
22
|
+
* @param propName - The property name to access
|
|
23
|
+
* @returns The own property value or `undefined`
|
|
24
|
+
*/
|
|
25
|
+
export declare function getOwnStaticProp<V, T extends StateContainerConstructor = StateContainerConstructor>(Type: T, propName: string): V | undefined;
|
|
16
26
|
/**
|
|
17
27
|
* Check if a class is marked as keepAlive.
|
|
18
28
|
* KeepAlive classes are never auto-disposed when ref count reaches 0.
|
|
29
|
+
* Inherited: a subclass keeps a base class's `keepAlive` unless overridden.
|
|
19
30
|
* @param Type - The class constructor to check
|
|
20
31
|
* @returns true if the class has `static keepAlive = true`
|
|
21
32
|
*/
|
|
@@ -23,19 +34,32 @@ export declare function isKeepAliveClass<T extends StateContainerConstructor>(Ty
|
|
|
23
34
|
/**
|
|
24
35
|
* Check if a class should be excluded from DevTools.
|
|
25
36
|
* Used to prevent infinite loops when DevTools tracks itself.
|
|
37
|
+
* Inherited: a subclass keeps a base class's exclusion unless overridden.
|
|
26
38
|
* @param Type - The class constructor to check
|
|
27
39
|
* @returns true if the class has `static __excludeFromDevTools = true`
|
|
28
40
|
*/
|
|
29
41
|
export declare function isExcludedFromDevTools<T extends StateContainerConstructor>(Type: T): boolean;
|
|
30
42
|
/**
|
|
31
43
|
* Get the per-class equality function set via `@blac({ equality })`, if any.
|
|
44
|
+
* Inherited: a subclass keeps a base class's equality fn unless overridden.
|
|
32
45
|
* @param Type - The class constructor to check
|
|
33
46
|
* @returns the equality function or `undefined`
|
|
34
47
|
*/
|
|
35
48
|
export declare function getClassEquality<T extends StateContainerConstructor>(Type: T): EqualityFn | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Get a class's minification-safe identity name.
|
|
51
|
+
* Own only: a subclass never inherits a base class's explicit `blacName`,
|
|
52
|
+
* since that would collapse two distinct blocs onto one identity.
|
|
53
|
+
* Falls back to `Type.name` (the runtime `constructor.name`) when unset.
|
|
54
|
+
* @param Type - The class constructor to check
|
|
55
|
+
* @returns the explicit `static blacName` or `Type.name`
|
|
56
|
+
*/
|
|
57
|
+
export declare function getBlacName<T extends StateContainerConstructor>(Type: T): string;
|
|
36
58
|
/**
|
|
37
59
|
* Get the per-class key function set via `@blac({ key })` or `static key = …`, if any.
|
|
38
60
|
* Used by the registry to derive a stable instance key from `args`.
|
|
61
|
+
* Own only: a subclass never inherits a base class's `key`, since a
|
|
62
|
+
* different `Args` shape would derive the wrong instance key.
|
|
39
63
|
* @param Type - The class constructor to check
|
|
40
64
|
* @returns the key function or `undefined`
|
|
41
65
|
*/
|
|
@@ -4,11 +4,4 @@
|
|
|
4
4
|
* Throws (dev) if it encounters a function or non-plain object — those belong in `deps`.
|
|
5
5
|
*/
|
|
6
6
|
export declare const DEFAULT_STRUCTURAL_KEY = "default";
|
|
7
|
-
/**
|
|
8
|
-
* Produce a stable string key for serializable args.
|
|
9
|
-
* - `undefined` / `void` args → `'default'` sentinel (no-args blocs stay on the default key).
|
|
10
|
-
* - Object keys are sorted for order-independence.
|
|
11
|
-
* - Arrays keep their insertion order.
|
|
12
|
-
* - Functions throw — they must be passed via `deps`, not `args`.
|
|
13
|
-
*/
|
|
14
7
|
export declare function structuralKey(args: unknown): string;
|
package/dist/watch/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { watch, instance } from './watch';
|
|
2
|
-
export type { WatchFn, BlocRef } from './watch';
|
|
2
|
+
export type { WatchFn, WatchOptions, BlocRef } from './watch';
|
package/dist/watch/watch.d.ts
CHANGED
|
@@ -31,6 +31,25 @@ export interface BlocRef<T extends StateContainerConstructor> {
|
|
|
31
31
|
*/
|
|
32
32
|
export declare function instance<T extends StateContainerConstructor>(BlocClass: T, args?: ExtractArgs<T>): BlocRef<T>;
|
|
33
33
|
type BlocInput = StateContainerConstructor | BlocRef<StateContainerConstructor>;
|
|
34
|
+
/**
|
|
35
|
+
* Options for `watch`.
|
|
36
|
+
*/
|
|
37
|
+
export interface WatchOptions {
|
|
38
|
+
/**
|
|
39
|
+
* When `false`, `watch` observes passively instead of owning the instance:
|
|
40
|
+
* it does not create a missing instance, and it does not take a real
|
|
41
|
+
* ownership ref on an existing one (so it never keeps an otherwise-
|
|
42
|
+
* unreferenced instance alive).
|
|
43
|
+
*
|
|
44
|
+
* If the instance does not exist yet when `watch` is called, the callback
|
|
45
|
+
* simply never fires for it — `watch` does not poll or wait for a later
|
|
46
|
+
* creation. Call `watch` again once the instance is known to exist (e.g.
|
|
47
|
+
* after some other owner has acquired it).
|
|
48
|
+
*
|
|
49
|
+
* Defaults to `true`.
|
|
50
|
+
*/
|
|
51
|
+
create?: boolean;
|
|
52
|
+
}
|
|
34
53
|
type ExtractInstance<T> = T extends BlocRef<infer C> ? InstanceType<C> : T extends StateContainerConstructor ? InstanceType<T> : never;
|
|
35
54
|
type ExtractInstances<T extends readonly BlocInput[]> = {
|
|
36
55
|
[K in keyof T]: ExtractInstance<T[K]>;
|
|
@@ -39,21 +58,21 @@ type ExtractInstances<T extends readonly BlocInput[]> = {
|
|
|
39
58
|
* Watch function signature for single bloc.
|
|
40
59
|
*/
|
|
41
60
|
export interface WatchSingleFn {
|
|
42
|
-
<T extends StateContainerConstructor>(bloc: T | BlocRef<T>, callback: (bloc: InstanceType<T>) => void | StopSymbol): () => void;
|
|
61
|
+
<T extends StateContainerConstructor>(bloc: T | BlocRef<T>, callback: (bloc: InstanceType<T>) => void | StopSymbol, options?: WatchOptions): () => void;
|
|
43
62
|
STOP: StopSymbol;
|
|
44
63
|
}
|
|
45
64
|
/**
|
|
46
65
|
* Watch function signature for multiple blocs.
|
|
47
66
|
*/
|
|
48
67
|
export interface WatchMultipleFn {
|
|
49
|
-
<T extends readonly BlocInput[]>(blocs: T, callback: (blocs: ExtractInstances<T>) => void | StopSymbol): () => void;
|
|
68
|
+
<T extends readonly BlocInput[]>(blocs: T, callback: (blocs: ExtractInstances<T>) => void | StopSymbol, options?: WatchOptions): () => void;
|
|
50
69
|
STOP: StopSymbol;
|
|
51
70
|
}
|
|
52
71
|
/**
|
|
53
72
|
* Combined watch function type.
|
|
54
73
|
*/
|
|
55
74
|
export interface WatchFn extends WatchSingleFn {
|
|
56
|
-
<T extends readonly BlocInput[]>(blocs: T, callback: (blocs: ExtractInstances<T>) => void | StopSymbol): () => void;
|
|
75
|
+
<T extends readonly BlocInput[]>(blocs: T, callback: (blocs: ExtractInstances<T>) => void | StopSymbol, options?: WatchOptions): () => void;
|
|
57
76
|
}
|
|
58
77
|
export declare const watch: WatchFn;
|
|
59
78
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blac/core",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.22",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Brendan Mullins <jsnanigans@gmail.com>",
|
|
6
6
|
"description": "Type-safe, class-based state management with proxy tracking and plugin system",
|
|
@@ -22,17 +22,8 @@
|
|
|
22
22
|
"testing": [
|
|
23
23
|
"./dist/testing.d.ts"
|
|
24
24
|
],
|
|
25
|
-
"debug": [
|
|
26
|
-
"./dist/debug.d.ts"
|
|
27
|
-
],
|
|
28
25
|
"plugins": [
|
|
29
26
|
"./dist/plugins.d.ts"
|
|
30
|
-
],
|
|
31
|
-
"watch": [
|
|
32
|
-
"./dist/watch-entry.d.ts"
|
|
33
|
-
],
|
|
34
|
-
"types": [
|
|
35
|
-
"./dist/types.d.ts"
|
|
36
27
|
]
|
|
37
28
|
}
|
|
38
29
|
},
|
|
@@ -47,16 +38,6 @@
|
|
|
47
38
|
"default": "./dist/index.cjs"
|
|
48
39
|
}
|
|
49
40
|
},
|
|
50
|
-
"./debug": {
|
|
51
|
-
"import": {
|
|
52
|
-
"types": "./dist/debug.d.ts",
|
|
53
|
-
"default": "./dist/debug.js"
|
|
54
|
-
},
|
|
55
|
-
"require": {
|
|
56
|
-
"types": "./dist/debug.d.cts",
|
|
57
|
-
"default": "./dist/debug.cjs"
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
41
|
"./plugins": {
|
|
61
42
|
"import": {
|
|
62
43
|
"types": "./dist/plugins.d.ts",
|
|
@@ -67,26 +48,6 @@
|
|
|
67
48
|
"default": "./dist/plugins.cjs"
|
|
68
49
|
}
|
|
69
50
|
},
|
|
70
|
-
"./watch": {
|
|
71
|
-
"import": {
|
|
72
|
-
"types": "./dist/watch-entry.d.ts",
|
|
73
|
-
"default": "./dist/watch-entry.js"
|
|
74
|
-
},
|
|
75
|
-
"require": {
|
|
76
|
-
"types": "./dist/watch-entry.d.cts",
|
|
77
|
-
"default": "./dist/watch-entry.cjs"
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
"./types": {
|
|
81
|
-
"import": {
|
|
82
|
-
"types": "./dist/types.d.ts",
|
|
83
|
-
"default": "./dist/types.js"
|
|
84
|
-
},
|
|
85
|
-
"require": {
|
|
86
|
-
"types": "./dist/types.d.cts",
|
|
87
|
-
"default": "./dist/types.cjs"
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
51
|
"./testing": {
|
|
91
52
|
"import": {
|
|
92
53
|
"types": "./dist/testing.d.ts",
|
|
@@ -118,27 +79,26 @@
|
|
|
118
79
|
{
|
|
119
80
|
"name": "@blac/core (ESM, brotli)",
|
|
120
81
|
"path": "dist/index.js",
|
|
121
|
-
"limit": "
|
|
82
|
+
"limit": "15 kB"
|
|
122
83
|
}
|
|
123
84
|
],
|
|
124
85
|
"dependencies": {
|
|
125
|
-
"@dirtytalk/structural": "^0.
|
|
86
|
+
"@dirtytalk/structural": "^0.1.2"
|
|
126
87
|
},
|
|
127
88
|
"devDependencies": {
|
|
128
|
-
"@size-limit/preset-small-lib": "^
|
|
129
|
-
"
|
|
130
|
-
"@testing-library/
|
|
131
|
-
"@
|
|
132
|
-
"
|
|
133
|
-
"
|
|
134
|
-
"
|
|
135
|
-
"
|
|
136
|
-
"publint": "^0.3.21",
|
|
89
|
+
"@size-limit/preset-small-lib": "^13.0.3",
|
|
90
|
+
"@testing-library/jest-dom": "^7.0.1",
|
|
91
|
+
"@testing-library/user-event": "^14.6.7",
|
|
92
|
+
"@types/node": "^26.4.1",
|
|
93
|
+
"arktype": "^2.2.3",
|
|
94
|
+
"fast-check": "^4.9.0",
|
|
95
|
+
"publint": "^0.3.24",
|
|
96
|
+
"size-limit": "^13.0.3",
|
|
137
97
|
"typescript": "^6.0.3",
|
|
138
|
-
"valibot": "^1.4.
|
|
139
|
-
"vite-plus": "^0.1.
|
|
140
|
-
"vitest": "npm:@voidzero-dev/vite-plus-test@
|
|
141
|
-
"zod": "^4.4
|
|
98
|
+
"valibot": "^1.4.2",
|
|
99
|
+
"vite-plus": "^0.1.24",
|
|
100
|
+
"vitest": "npm:@voidzero-dev/vite-plus-test@0.1.24",
|
|
101
|
+
"zod": "^4.5.4"
|
|
142
102
|
},
|
|
143
103
|
"scripts": {
|
|
144
104
|
"dev": "vp pack --watch",
|
|
@@ -153,6 +113,7 @@
|
|
|
153
113
|
"coverage": "vp test run --coverage",
|
|
154
114
|
"verify": "node ../../scripts/run-workspace-bin.mjs publint",
|
|
155
115
|
"typecheck": "tsc --noEmit",
|
|
116
|
+
"api:check": "for f in api-extractor.*.json; do api-extractor run -c \"$f\" || exit 1; done",
|
|
156
117
|
"size": "size-limit",
|
|
157
118
|
"deploy": "pnpm publish --access public"
|
|
158
119
|
}
|