getDependenciesApi().set
1. Overview
- What it does: Sets one router dependency by name.
undefined value is silently ignored (feature for conditional configuration). Warns when overwriting an existing dependency with a different value.
- When to use:
- For adding a single dependency (service, API client, analytics)
- For conditional configuration:
depsApi.set("analytics", __DEV__ ? mockAnalytics : undefined)
- For updating an existing dependency (with warning)
2. Signature
import { getDependenciesApi } from "@real-router/core/api";
const depsApi = getDependenciesApi(router);
depsApi.set<K extends keyof Dependencies & string>(
name: K,
value: Dependencies[K],
): void;
Usage Examples
import { getDependenciesApi } from "@real-router/core/api";
const depsApi = getDependenciesApi(router);
// Add dependency
depsApi.set("apiClient", new ApiClient());
// Conditional configuration (undefined ignored)
depsApi.set("devTools", __DEV__ ? devToolsInstance : undefined);
// Update existing dependency (outputs warning)
depsApi.set("config", newConfig); // console.warn
// Idempotency (same value -- no warning)
depsApi.set("version", "1.0.0");
depsApi.set("version", "1.0.0"); // No warning
3. Parameters
name (required)
- Type:
K extends keyof Dependencies & string
- Purpose: Dependency name
- Allowed values: Any string (including empty)
- On error:
TypeError -- [router.setDependency]: dependency name must be a string, got {type}
value (required)
- Type:
Dependencies[K]
- Purpose: Dependency value
- Allowed values: Any value, including:
- Primitives:
number, string, boolean, null, 0, false, ""
- Objects: plain objects, class instances, functions, arrays
- Special:
Infinity, -Infinity, NaN
- Circular references
- Special behavior:
undefined -- silently does nothing (dependency is not set, no error)
null -- set as a normal value
4. Return Value
- Type:
void
- Description: Does not return a value.
5. Side Effects
- State change: Adds or updates dependency in the store
- Warnings:
console.warn when overwriting an existing dependency with a different value
console.warn when reaching the warn threshold (20% of maxDependencies, i.e. 20 at default limit of 100)
console.error when reaching the error threshold (50% of maxDependencies, i.e. 50 at default limit of 100)
- Errors:
Error when exceeding maxDependencies limit (default: 100)
- NaN idempotency: Overwriting
NaN with NaN does NOT trigger a warning (treated as same value via Number.isNaN())
6. Possible Errors
| Condition |
Error Type |
Message |
| Router disposed |
RouterError |
Code: DISPOSED |
name is not a string |
TypeError |
[router.setDependency]: dependency name must be a string, got {type} |
| Dependency limit exceeded (default 100) |
Error |
[router.setDependency] Dependency limit exceeded (100). Current: {count}... |
Error Examples
import { getDependenciesApi } from "@real-router/core/api";
const depsApi = getDependenciesApi(router);
// TypeError: invalid name
depsApi.set(123, "value");
// TypeError: [router.setDependency]: dependency name must be a string, got number
depsApi.set(null, "value");
// TypeError: [router.setDependency]: dependency name must be a string, got object
// RouterError: router disposed
router.dispose();
depsApi.set("foo", "bar");
// RouterError: DISPOSED
// Error: limit exceeded (after adding 100 dependencies)
depsApi.set("dep101", value);
// Error: [router.setDependency] Dependency limit exceeded (100)...
7. Related Methods
| Method |
When to use |
getDependenciesApi().get |
Get dependency by name |
getDependenciesApi().setAll |
Set multiple dependencies |
getDependenciesApi().has |
Check existence |
getDependenciesApi().remove |
Remove dependency |
getDependenciesApi().getAll |
Get all dependencies |
getDependenciesApi().reset |
Clear all dependencies |
8. Behavior
Main Scenarios
- New dependency: Added without warnings
- Overwrite with different value: Updated with
console.warn
- Overwrite with same value: Updated without warning (idempotent)
undefined value: Silently ignored (conditional configuration)
- NaN idempotency:
NaN overwrites NaN without warning
Test Examples
import { getDependenciesApi } from "@real-router/core/api";
const depsApi = getDependenciesApi(router);
// Set new dependency
depsApi.set("bar", "hello");
expect(depsApi.get("bar")).toBe("hello");
// Overwrite existing
depsApi.set("foo", 2);
expect(depsApi.get("foo")).toBe(2);
// undefined ignored
depsApi.set("foo", undefined);
expect(depsApi.get("foo")).toBe(1); // Kept initial value
// Conditional configuration
const isDev = false;
depsApi.set("devLogger", isDev ? console : undefined);
expect(depsApi.has("devLogger")).toBe(false);
Overwrite Warnings
// Warning when overwriting with different value
depsApi.set("foo", 1);
depsApi.set("foo", 2); // console.warn
// No warning for same value
depsApi.set("foo", 42);
depsApi.set("foo", 42); // No warning
// Special NaN handling
depsApi.set("foo", NaN);
depsApi.set("foo", NaN); // No warning (NaN === NaN for idempotency check)
Prototype Pollution Protection
// Safe due to Object.create(null)
depsApi.set("constructor", "safe1");
depsApi.set("__proto__", "safe2");
depsApi.set("hasOwnProperty", "safe3");
expect(depsApi.get("constructor")).toBe("safe1");
expect(depsApi.get("__proto__")).toBe("safe2");
expect(depsApi.get("hasOwnProperty")).toBe("safe3");
Value Types
// Falsy values (except undefined)
depsApi.set("foo", 0); // OK
depsApi.set("bar", false); // OK
depsApi.set("baz", ""); // OK
depsApi.set("qux", null); // OK
// Special numeric values
depsApi.set("inf", Infinity); // OK
depsApi.set("neg", -Infinity); // OK
depsApi.set("nan", NaN); // OK
// Functions and classes
depsApi.set("factory", () => ({ value: 42 }));
depsApi.set("Service", ServiceClass);
// Circular references
const obj = { name: "circular" };
obj.self = obj;
depsApi.set("circular", obj); // OK
Dependency Limits
Default thresholds (with maxDependencies = 100):
| Threshold |
Count |
Action |
| Warn |
20 |
console.warn |
| Error |
50 |
console.error |
| Max |
100 |
throws Error |
// Overwriting existing at limit -- allowed (doesn't increase count)
depsApi.set("dep0", 999); // OK
Disposed Router
router.dispose();
depsApi.set("foo", "bar");
// throws RouterError with code DISPOSED
Edge Cases
- Empty string as key: Accepted
undefined as value: Silently ignored (no changes, no error)
null as value: Set normally
- NaN idempotency:
NaN overwrites NaN without warning
- Circular references: Supported
- Overwriting at limit: Allowed (overwrite does not increase count)
9. Migration
Old API (removed)
// Old -- no longer available
router.setDependency("apiClient", new ApiClient());
// Fluent chaining -- no longer available
router
.setDependency("analytics", analyticsService)
.setDependency("store", reduxStore);
New API
import { getDependenciesApi } from "@real-router/core/api";
const depsApi = getDependenciesApi(router);
// New -- standalone API
depsApi.set("apiClient", new ApiClient());
// No fluent chaining (returns void), use separate calls
depsApi.set("analytics", analyticsService);
depsApi.set("store", reduxStore);
Key Differences
| Aspect |
Old (router.setDependency) |
New (getDependenciesApi(router).set) |
| Access |
Method on router instance |
Standalone API function |
| Return value |
Router (fluent interface) |
void |
| Chaining |
Supported |
Not supported |
| Tree-shaking |
Always bundled |
Tree-shakeable |
| Import |
N/A (on router) |
import { getDependenciesApi } |