@blac/react 2.0.15 → 2.0.17

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.
@@ -1,11 +1,12 @@
1
1
  import type { ReactElement } from 'react';
2
2
  import type { RenderResult } from '@testing-library/react';
3
- import type { StateContainerConstructor } from '@blac/core';
3
+ import type { ExtractArgs, StateContainerConstructor } from '@blac/core';
4
4
  import { StateContainerRegistry } from '@blac/core';
5
5
  import { type CubitStubOptions } from '@blac/core/testing';
6
6
  interface RenderWithBlocOptions<T extends StateContainerConstructor> extends CubitStubOptions<T> {
7
7
  bloc: T;
8
- instanceKey?: string;
8
+ /** Args used to resolve which instance the stub is registered under. */
9
+ args?: ExtractArgs<T>;
9
10
  }
10
11
  export declare function renderWithBloc<T extends StateContainerConstructor>(ui: ReactElement, options: RenderWithBlocOptions<T>): RenderResult & {
11
12
  bloc: InstanceType<T>;
package/dist/testing.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import type { ReactElement } from 'react';
2
2
  import type { RenderResult } from '@testing-library/react';
3
- import type { StateContainerConstructor } from '@blac/core';
3
+ import type { ExtractArgs, StateContainerConstructor } from '@blac/core';
4
4
  import { StateContainerRegistry } from '@blac/core';
5
5
  import { type CubitStubOptions } from '@blac/core/testing';
6
6
  interface RenderWithBlocOptions<T extends StateContainerConstructor> extends CubitStubOptions<T> {
7
7
  bloc: T;
8
- instanceKey?: string;
8
+ /** Args used to resolve which instance the stub is registered under. */
9
+ args?: ExtractArgs<T>;
9
10
  }
10
11
  export declare function renderWithBloc<T extends StateContainerConstructor>(ui: ReactElement, options: RenderWithBlocOptions<T>): RenderResult & {
11
12
  bloc: InstanceType<T>;
package/dist/testing.js CHANGED
@@ -3,11 +3,14 @@ import { createCubitStub, registerOverride } from "@blac/core/testing";
3
3
  import { render } from "@testing-library/react";
4
4
  //#region src/testing.ts
5
5
  function renderWithBloc(ui, options) {
6
- const { bloc: BlocClass, instanceKey, ...stubOptions } = options;
6
+ const { bloc: BlocClass, args, ...stubOptions } = options;
7
7
  const previous = getRegistry();
8
8
  setRegistry(new StateContainerRegistry());
9
- const instance = createCubitStub(BlocClass, stubOptions);
10
- registerOverride(BlocClass, instance, instanceKey);
9
+ const instance = createCubitStub(BlocClass, {
10
+ ...stubOptions,
11
+ args
12
+ });
13
+ registerOverride(BlocClass, instance, args);
11
14
  let renderResult;
12
15
  try {
13
16
  renderResult = render(ui);
@@ -1 +1 @@
1
- {"version":3,"file":"testing.js","names":[],"sources":["../src/testing.ts"],"sourcesContent":["import type { ReactElement } from 'react';\nimport type { RenderResult } from '@testing-library/react';\nimport type { StateContainerConstructor } from '@blac/core';\nimport { StateContainerRegistry, getRegistry, setRegistry } from '@blac/core';\nimport {\n registerOverride,\n createCubitStub,\n type CubitStubOptions,\n} from '@blac/core/testing';\nimport { render } from '@testing-library/react';\n\ninterface RenderWithBlocOptions<\n T extends StateContainerConstructor,\n> extends CubitStubOptions<T> {\n bloc: T;\n instanceKey?: string;\n}\n\nexport function renderWithBloc<T extends StateContainerConstructor>(\n ui: ReactElement,\n options: RenderWithBlocOptions<T>,\n): RenderResult & { bloc: InstanceType<T> } {\n const { bloc: BlocClass, instanceKey, ...stubOptions } = options;\n\n const previous = getRegistry();\n const testRegistry = new StateContainerRegistry();\n setRegistry(testRegistry);\n\n const instance = createCubitStub(BlocClass, stubOptions);\n registerOverride(BlocClass, instance, instanceKey);\n\n let renderResult: RenderResult;\n try {\n renderResult = render(ui);\n } catch (e) {\n setRegistry(previous);\n throw e;\n }\n\n const originalUnmount = renderResult.unmount;\n renderResult.unmount = () => {\n originalUnmount();\n setRegistry(previous);\n };\n\n return {\n ...renderResult,\n bloc: instance,\n };\n}\n\nexport function renderWithRegistry(\n ui: ReactElement,\n setup: (registry: StateContainerRegistry) => void,\n): RenderResult {\n const previous = getRegistry();\n const testRegistry = new StateContainerRegistry();\n setRegistry(testRegistry);\n\n try {\n setup(testRegistry);\n } catch (e) {\n setRegistry(previous);\n throw e;\n }\n\n let renderResult: RenderResult;\n try {\n renderResult = render(ui);\n } catch (e) {\n setRegistry(previous);\n throw e;\n }\n\n const originalUnmount = renderResult.unmount;\n renderResult.unmount = () => {\n originalUnmount();\n setRegistry(previous);\n };\n\n return renderResult;\n}\n"],"mappings":";;;;AAkBA,SAAgB,eACd,IACA,SAC0C;CAC1C,MAAM,EAAE,MAAM,WAAW,aAAa,GAAG,gBAAgB;CAEzD,MAAM,WAAW,aAAa;CAE9B,YAAY,IADa,wBACD,CAAC;CAEzB,MAAM,WAAW,gBAAgB,WAAW,YAAY;CACxD,iBAAiB,WAAW,UAAU,YAAY;CAElD,IAAI;CACJ,IAAI;EACF,eAAe,OAAO,GAAG;UAClB,GAAG;EACV,YAAY,SAAS;EACrB,MAAM;;CAGR,MAAM,kBAAkB,aAAa;CACrC,aAAa,gBAAgB;EAC3B,iBAAiB;EACjB,YAAY,SAAS;;CAGvB,OAAO;EACL,GAAG;EACH,MAAM;EACP;;AAGH,SAAgB,mBACd,IACA,OACc;CACd,MAAM,WAAW,aAAa;CAC9B,MAAM,eAAe,IAAI,wBAAwB;CACjD,YAAY,aAAa;CAEzB,IAAI;EACF,MAAM,aAAa;UACZ,GAAG;EACV,YAAY,SAAS;EACrB,MAAM;;CAGR,IAAI;CACJ,IAAI;EACF,eAAe,OAAO,GAAG;UAClB,GAAG;EACV,YAAY,SAAS;EACrB,MAAM;;CAGR,MAAM,kBAAkB,aAAa;CACrC,aAAa,gBAAgB;EAC3B,iBAAiB;EACjB,YAAY,SAAS;;CAGvB,OAAO"}
1
+ {"version":3,"file":"testing.js","names":[],"sources":["../src/testing.ts"],"sourcesContent":["import type { ReactElement } from 'react';\nimport type { RenderResult } from '@testing-library/react';\nimport type { ExtractArgs, StateContainerConstructor } from '@blac/core';\nimport { StateContainerRegistry, getRegistry, setRegistry } from '@blac/core';\nimport {\n registerOverride,\n createCubitStub,\n type CubitStubOptions,\n} from '@blac/core/testing';\nimport { render } from '@testing-library/react';\n\ninterface RenderWithBlocOptions<\n T extends StateContainerConstructor,\n> extends CubitStubOptions<T> {\n bloc: T;\n /** Args used to resolve which instance the stub is registered under. */\n args?: ExtractArgs<T>;\n}\n\nexport function renderWithBloc<T extends StateContainerConstructor>(\n ui: ReactElement,\n options: RenderWithBlocOptions<T>,\n): RenderResult & { bloc: InstanceType<T> } {\n const { bloc: BlocClass, args, ...stubOptions } = options;\n\n const previous = getRegistry();\n const testRegistry = new StateContainerRegistry();\n setRegistry(testRegistry);\n\n // Pass args explicitly so createCubitStub calls initConfig → init().\n const instance = createCubitStub(BlocClass, { ...stubOptions, args } as any);\n registerOverride(BlocClass, instance, args);\n\n let renderResult: RenderResult;\n try {\n renderResult = render(ui);\n } catch (e) {\n setRegistry(previous);\n throw e;\n }\n\n const originalUnmount = renderResult.unmount;\n renderResult.unmount = () => {\n originalUnmount();\n setRegistry(previous);\n };\n\n return {\n ...renderResult,\n bloc: instance,\n };\n}\n\nexport function renderWithRegistry(\n ui: ReactElement,\n setup: (registry: StateContainerRegistry) => void,\n): RenderResult {\n const previous = getRegistry();\n const testRegistry = new StateContainerRegistry();\n setRegistry(testRegistry);\n\n try {\n setup(testRegistry);\n } catch (e) {\n setRegistry(previous);\n throw e;\n }\n\n let renderResult: RenderResult;\n try {\n renderResult = render(ui);\n } catch (e) {\n setRegistry(previous);\n throw e;\n }\n\n const originalUnmount = renderResult.unmount;\n renderResult.unmount = () => {\n originalUnmount();\n setRegistry(previous);\n };\n\n return renderResult;\n}\n"],"mappings":";;;;AAmBA,SAAgB,eACd,IACA,SAC0C;CAC1C,MAAM,EAAE,MAAM,WAAW,MAAM,GAAG,gBAAgB;CAElD,MAAM,WAAW,YAAY;CAE7B,YAAY,IADa,uBACF,CAAC;CAGxB,MAAM,WAAW,gBAAgB,WAAW;EAAE,GAAG;EAAa;CAAK,CAAQ;CAC3E,iBAAiB,WAAW,UAAU,IAAI;CAE1C,IAAI;CACJ,IAAI;EACF,eAAe,OAAO,EAAE;CAC1B,SAAS,GAAG;EACV,YAAY,QAAQ;EACpB,MAAM;CACR;CAEA,MAAM,kBAAkB,aAAa;CACrC,aAAa,gBAAgB;EAC3B,gBAAgB;EAChB,YAAY,QAAQ;CACtB;CAEA,OAAO;EACL,GAAG;EACH,MAAM;CACR;AACF;AAEA,SAAgB,mBACd,IACA,OACc;CACd,MAAM,WAAW,YAAY;CAC7B,MAAM,eAAe,IAAI,uBAAuB;CAChD,YAAY,YAAY;CAExB,IAAI;EACF,MAAM,YAAY;CACpB,SAAS,GAAG;EACV,YAAY,QAAQ;EACpB,MAAM;CACR;CAEA,IAAI;CACJ,IAAI;EACF,eAAe,OAAO,EAAE;CAC1B,SAAS,GAAG;EACV,YAAY,QAAQ;EACpB,MAAM;CACR;CAEA,MAAM,kBAAkB,aAAa;CACrC,aAAa,gBAAgB;EAC3B,gBAAgB;EAChB,YAAY,QAAQ;CACtB;CAEA,OAAO;AACT"}
package/dist/types.d.ts CHANGED
@@ -1,13 +1,16 @@
1
1
  import type { ExtractArgs, ExtractState, InstanceReadonlyState, StateContainerConstructor } from '@blac/core';
2
2
  import type { RefObject } from 'react';
3
3
  /**
4
- * Conditional `args` field: required when the bloc declares Args, forbidden
5
- * (type `never`) when the bloc uses the default `void` Args.
4
+ * Conditional `args` field:
5
+ * - When the bloc uses the default `void` Args: args is forbidden (type `never`).
6
+ * - When the bloc declares Args: args is optional (may be inherited from a
7
+ * `BlocProvider` ancestor at runtime; omitting it resolves to the provider
8
+ * args or the default key).
6
9
  */
7
10
  type ArgsOption<T extends StateContainerConstructor> = ExtractArgs<T> extends void ? {
8
11
  args?: never;
9
12
  } : {
10
- args: ExtractArgs<T>;
13
+ args?: ExtractArgs<T>;
11
14
  };
12
15
  /**
13
16
  * Configuration options for {@link useBloc}.
@@ -15,16 +18,15 @@ type ArgsOption<T extends StateContainerConstructor> = ExtractArgs<T> extends vo
15
18
  * @template TBloc - The state container constructor type
16
19
  *
17
20
  * @remarks
21
+ * Instance identity is derived entirely from `args`. For a per-mount private
22
+ * instance (like the old `instanceId: useId()` pattern) pass a stable unique
23
+ * object: `{ args: { _id: useId() } }`.
24
+ *
18
25
  * The `dependencies` option from BlaC v1 has been removed — use `select`
19
26
  * instead. Codemod: rename `dependencies` → `select`; the return value is
20
27
  * still a tuple/array compared per-index via `Object.is`.
21
28
  */
22
29
  export type UseBlocOptions<TBloc extends StateContainerConstructor> = ArgsOption<TBloc> & {
23
- /**
24
- * Per-consumer instance identifier. Overrides any `instanceId` provided
25
- * by an ancestor {@link BlocProvider}.
26
- */
27
- instanceId?: string | number;
28
30
  /**
29
31
  * Per-consumer re-render selector. When provided, the hook re-renders
30
32
  * only when the returned array's elements change (Object.is per index).
package/dist/useBloc.d.ts CHANGED
@@ -15,12 +15,19 @@ import type { UseBlocOptions, UseBlocReturn } from './types';
15
15
  *
16
16
  * Lifecycle:
17
17
  * - The bloc is acquired from the registry on mount and released on
18
- * unmount. The instance key is the explicit `options.instanceId`, then
19
- * the surrounding {@link BlocProvider} context, then the default key.
18
+ * unmount. The instance key is derived from `options.args` (own args),
19
+ * then the surrounding {@link BlocProvider} context args for this bloc,
20
+ * then the default key (no args).
20
21
  * - `options.onMount` fires after the bloc is acquired; `options.onUnmount`
21
22
  * fires *before* the registry releases its ref, so the bloc is still
22
23
  * alive when the callback runs.
23
24
  *
25
+ * Per-mount private instance:
26
+ * ```ts
27
+ * const id = useId();
28
+ * const [state, bloc] = useBloc(MyBloc, { args: { _id: id } });
29
+ * ```
30
+ *
24
31
  * @template T - The state container constructor type (inferred from BlocClass)
25
32
  * @param BlocClass - The state container class to connect to
26
33
  * @param options - Configuration options
@@ -38,9 +45,9 @@ import type { UseBlocOptions, UseBlocReturn } from './types';
38
45
  * });
39
46
  * ```
40
47
  *
41
- * @example Named instance
48
+ * @example Args-based shared instance
42
49
  * ```ts
43
- * const [state, bloc] = useBloc(MyBloc, { instanceId: 'cart-42' });
50
+ * const [state, bloc] = useBloc(UserBloc, { args: { userId: 'alice' } });
44
51
  * ```
45
52
  */
46
53
  export declare function useBloc<T extends StateContainerConstructor = StateContainerConstructor>(BlocClass: T, options?: UseBlocOptions<T>): UseBlocReturn<T, ExtractState<T>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blac/react",
3
- "version": "2.0.15",
3
+ "version": "2.0.17",
4
4
  "license": "MIT",
5
5
  "author": "Brendan Mullins <jsnanigans@gmail.com>",
6
6
  "description": "React bindings for BlaC — useBloc hook with automatic re-render optimization",
@@ -64,14 +64,27 @@
64
64
  "bloc",
65
65
  "bloc-pattern"
66
66
  ],
67
+ "size-limit": [
68
+ {
69
+ "name": "@blac/react (ESM, brotli, excl. peers)",
70
+ "path": "dist/index.js",
71
+ "limit": "3.5 kB",
72
+ "ignore": [
73
+ "react",
74
+ "react-dom",
75
+ "@blac/core",
76
+ "@types/react"
77
+ ]
78
+ }
79
+ ],
67
80
  "dependencies": {
68
- "@dirtytalk/structural": "^0.0.3"
81
+ "@dirtytalk/structural": "^0.0.5"
69
82
  },
70
83
  "peerDependencies": {
71
84
  "@testing-library/react": "^14.0.0 || ^15.0.0 || ^16.0.0",
72
85
  "@types/react": "^18.0.0 || ^19.0.0",
73
86
  "react": "^18.0.0 || ^19.0.0",
74
- "@blac/core": "^2.0.15"
87
+ "@blac/core": "^2.0.17"
75
88
  },
76
89
  "peerDependenciesMeta": {
77
90
  "@types/react": {
@@ -85,24 +98,29 @@
85
98
  }
86
99
  },
87
100
  "devDependencies": {
101
+ "@size-limit/preset-small-lib": "^11.1.6",
102
+ "size-limit": "^11.1.6",
103
+ "@babel/core": "^7.28.0",
104
+ "@rolldown/plugin-babel": "^0.2.3",
88
105
  "@testing-library/dom": "^10.4.1",
89
- "@testing-library/jest-dom": "^6.6.4",
90
- "@testing-library/react": "^16.3.0",
106
+ "@testing-library/jest-dom": "^6.9.1",
107
+ "@testing-library/react": "^16.3.2",
91
108
  "@testing-library/user-event": "^14.6.1",
92
- "@types/react": "^19.1.9",
93
- "@types/react-dom": "^19.1.7",
94
- "@vitejs/plugin-react": "^4.7.0",
109
+ "@types/babel__core": "^7.20.5",
110
+ "@types/react": "^19.2.15",
111
+ "@types/react-dom": "^19.2.3",
112
+ "@vitejs/plugin-react": "^6.0.2",
95
113
  "babel-plugin-react-compiler": "^1.0.0",
96
- "happy-dom": "^18.0.1",
97
- "jsdom": "^26.1.0",
98
- "publint": "^0.3.12",
99
- "react": "^19.1.1",
100
- "react-dom": "^19.1.1",
101
- "typescript": "^5.9.2",
114
+ "happy-dom": "^20.9.0",
115
+ "jsdom": "^29.1.1",
116
+ "publint": "^0.3.21",
117
+ "react": "^19.2.6",
118
+ "react-dom": "^19.2.6",
119
+ "typescript": "^6.0.3",
102
120
  "vite": "npm:@voidzero-dev/vite-plus-core@latest",
121
+ "vite-plus": "^0.1.23",
103
122
  "vitest": "npm:@voidzero-dev/vite-plus-test@latest",
104
- "vite-plus": "latest",
105
- "@blac/core": "2.0.15"
123
+ "@blac/core": "2.0.17"
106
124
  },
107
125
  "scripts": {
108
126
  "dev": "vp pack --watch",
@@ -121,6 +139,7 @@
121
139
  "test:both": "pnpm test && echo '\n\n=== Running tests WITH React Compiler ===\n' && pnpm test:compiler",
122
140
  "verify": "node ../../scripts/run-workspace-bin.mjs publint",
123
141
  "typecheck": "tsc --noEmit",
142
+ "size": "size-limit",
124
143
  "deploy": "pnpm publish --access public"
125
144
  }
126
145
  }