@blac/core 2.0.0-rc.6 → 2.0.0-rc.9
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/dist/adapter/framework-adapter.d.ts +114 -0
- package/dist/adapter/index.d.ts +8 -0
- package/dist/constants.d.ts +82 -0
- package/dist/core/Cubit.d.ts +82 -0
- package/dist/core/StateContainer.d.ts +205 -0
- package/dist/core/StateContainerRegistry.d.ts +176 -0
- package/dist/core/Vertex.d.ts +113 -0
- package/dist/index.cjs +1153 -493
- package/dist/index.d.cts +19 -885
- package/dist/index.d.ts +18 -884
- package/dist/index.js +1117 -491
- package/dist/logging/Logger.d.ts +57 -0
- package/dist/plugin/BlacPlugin.d.ts +115 -0
- package/dist/plugin/PluginManager.d.ts +63 -0
- package/dist/registry/index.d.ts +20 -0
- package/dist/test-utils/index.d.ts +43 -0
- package/dist/tracking/dependency-tracker.d.ts +21 -0
- package/dist/tracking/getter-tracker.d.ts +31 -0
- package/dist/tracking/index.d.ts +38 -0
- package/dist/tracking/path-utils.d.ts +39 -0
- package/dist/tracking/proxy-tracker.d.ts +88 -0
- package/dist/types/branded.d.ts +9 -0
- package/dist/types/events.d.ts +13 -0
- package/dist/types/utilities.d.ts +18 -0
- package/dist/utils/equality.d.ts +9 -0
- package/dist/utils/idGenerator.d.ts +76 -0
- package/dist/utils/immutable.d.ts +16 -0
- package/dist/utils/stack-trace.d.ts +19 -0
- package/dist/utils/static-props.d.ts +29 -0
- package/package.json +17 -5
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework Adapter - Reusable logic for integrating BlaC with any reactive framework
|
|
3
|
+
*
|
|
4
|
+
* This module provides framework-agnostic utilities for:
|
|
5
|
+
* - Subscription management (auto-tracking, manual deps, no-tracking modes)
|
|
6
|
+
* - Snapshot generation (state proxies with tracking)
|
|
7
|
+
* - External dependency management (cross-bloc subscriptions)
|
|
8
|
+
* - Change detection (state and getter tracking)
|
|
9
|
+
*
|
|
10
|
+
* Can be used to integrate BlaC with React, Vue, Solid, Svelte, Angular, etc.
|
|
11
|
+
*/
|
|
12
|
+
import type { StateContainer } from '../core/StateContainer';
|
|
13
|
+
import type { TrackerState, GetterTrackerState } from '../tracking';
|
|
14
|
+
import type { ExtractState } from '../types/utilities';
|
|
15
|
+
/**
|
|
16
|
+
* Framework-agnostic adapter state
|
|
17
|
+
* Frameworks should store this in their component state mechanism
|
|
18
|
+
*/
|
|
19
|
+
export interface AdapterState<TBloc extends StateContainer<any>> {
|
|
20
|
+
/** State property tracker */
|
|
21
|
+
tracker: TrackerState<ExtractState<TBloc>> | null;
|
|
22
|
+
/** Manual dependencies cache */
|
|
23
|
+
manualDepsCache: unknown[] | null;
|
|
24
|
+
/** Getter tracking state */
|
|
25
|
+
getterTracker: GetterTrackerState | null;
|
|
26
|
+
/** Cached proxied bloc instance */
|
|
27
|
+
proxiedBloc: TBloc | null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Configuration for manual dependencies mode
|
|
31
|
+
*/
|
|
32
|
+
export interface ManualDepsConfig<TBloc extends StateContainer<any>> {
|
|
33
|
+
dependencies: (state: any, bloc: TBloc) => unknown[];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Subscription callback type
|
|
37
|
+
* Called when the framework should re-render
|
|
38
|
+
*/
|
|
39
|
+
export type SubscriptionCallback = () => void;
|
|
40
|
+
/**
|
|
41
|
+
* Subscription function type
|
|
42
|
+
* Returns an unsubscribe function
|
|
43
|
+
*/
|
|
44
|
+
export type SubscribeFunction = (callback: SubscriptionCallback) => () => void;
|
|
45
|
+
/**
|
|
46
|
+
* Snapshot function type
|
|
47
|
+
* Returns the current state (possibly proxied)
|
|
48
|
+
*/
|
|
49
|
+
export type SnapshotFunction<TState> = () => TState;
|
|
50
|
+
/**
|
|
51
|
+
* External dependency manager
|
|
52
|
+
* Handles subscriptions to external blocs accessed in getters
|
|
53
|
+
*/
|
|
54
|
+
export declare class ExternalDependencyManager {
|
|
55
|
+
private subscriptions;
|
|
56
|
+
private previousDeps;
|
|
57
|
+
/**
|
|
58
|
+
* Check if dependencies have changed
|
|
59
|
+
*/
|
|
60
|
+
private areDependenciesEqual;
|
|
61
|
+
/**
|
|
62
|
+
* Update external subscriptions
|
|
63
|
+
* @param getterTracker - The getter tracker state
|
|
64
|
+
* @param rawInstance - The raw bloc instance (exclude from subscriptions)
|
|
65
|
+
* @param onGetterChange - Callback when external getter changes
|
|
66
|
+
* @returns Whether subscriptions were updated
|
|
67
|
+
*/
|
|
68
|
+
updateSubscriptions(getterTracker: GetterTrackerState | null, rawInstance: StateContainer<any>, onGetterChange: () => void): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Cleanup all subscriptions
|
|
71
|
+
*/
|
|
72
|
+
cleanup(): void;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Create a subscription function for auto-tracking mode
|
|
76
|
+
*/
|
|
77
|
+
export declare function createAutoTrackSubscribe<TBloc extends StateContainer<any>>(instance: TBloc, adapterState: AdapterState<TBloc>): SubscribeFunction;
|
|
78
|
+
/**
|
|
79
|
+
* Create a subscription function for manual dependencies mode
|
|
80
|
+
*/
|
|
81
|
+
export declare function createManualDepsSubscribe<TBloc extends StateContainer<any>>(instance: TBloc, adapterState: AdapterState<TBloc>, config: ManualDepsConfig<TBloc>): SubscribeFunction;
|
|
82
|
+
/**
|
|
83
|
+
* Create a subscription function for no-tracking mode
|
|
84
|
+
*/
|
|
85
|
+
export declare function createNoTrackSubscribe<TBloc extends StateContainer<any>>(instance: TBloc): SubscribeFunction;
|
|
86
|
+
/**
|
|
87
|
+
* Create a snapshot function for auto-tracking mode
|
|
88
|
+
*/
|
|
89
|
+
export declare function createAutoTrackSnapshot<TBloc extends StateContainer<any>>(instance: TBloc, adapterState: AdapterState<TBloc>): SnapshotFunction<ExtractState<TBloc>>;
|
|
90
|
+
/**
|
|
91
|
+
* Create a snapshot function for manual dependencies mode
|
|
92
|
+
*/
|
|
93
|
+
export declare function createManualDepsSnapshot<TBloc extends StateContainer<any>>(instance: TBloc, adapterState: AdapterState<TBloc>, config: ManualDepsConfig<TBloc>): SnapshotFunction<ExtractState<TBloc>>;
|
|
94
|
+
/**
|
|
95
|
+
* Create a snapshot function for no-tracking mode
|
|
96
|
+
*/
|
|
97
|
+
export declare function createNoTrackSnapshot<TBloc extends StateContainer<any>>(instance: TBloc): SnapshotFunction<ExtractState<TBloc>>;
|
|
98
|
+
/**
|
|
99
|
+
* Initialize adapter state for auto-tracking mode
|
|
100
|
+
*/
|
|
101
|
+
export declare function initAutoTrackState<TBloc extends StateContainer<any>>(instance: TBloc): AdapterState<TBloc>;
|
|
102
|
+
/**
|
|
103
|
+
* Initialize adapter state for manual dependencies mode
|
|
104
|
+
*/
|
|
105
|
+
export declare function initManualDepsState<TBloc extends StateContainer<any>>(instance: TBloc): AdapterState<TBloc>;
|
|
106
|
+
/**
|
|
107
|
+
* Initialize adapter state for no-tracking mode
|
|
108
|
+
*/
|
|
109
|
+
export declare function initNoTrackState<TBloc extends StateContainer<any>>(instance: TBloc): AdapterState<TBloc>;
|
|
110
|
+
/**
|
|
111
|
+
* Disable getter tracking (call after render completes)
|
|
112
|
+
*/
|
|
113
|
+
export declare function disableGetterTracking<TBloc extends StateContainer<any>>(adapterState: AdapterState<TBloc>, rawInstance: TBloc): void;
|
|
114
|
+
//# sourceMappingURL=framework-adapter.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework Adapter
|
|
3
|
+
*
|
|
4
|
+
* Reusable utilities for integrating BlaC with any reactive framework.
|
|
5
|
+
* Use these to build integrations for React, Vue, Solid, Svelte, Angular, etc.
|
|
6
|
+
*/
|
|
7
|
+
export { type AdapterState, type ManualDepsConfig, type SubscriptionCallback, type SubscribeFunction, type SnapshotFunction, ExternalDependencyManager, createAutoTrackSubscribe, createManualDepsSubscribe, createNoTrackSubscribe, createAutoTrackSnapshot, createManualDepsSnapshot, createNoTrackSnapshot, initAutoTrackState, initManualDepsState, initNoTrackState, disableGetterTracking, } from './framework-adapter';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default configuration constants for BlaC
|
|
3
|
+
*
|
|
4
|
+
* Centralized location for all magic numbers and default values.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Default configuration constants for BlaC
|
|
8
|
+
*/
|
|
9
|
+
export declare const BLAC_DEFAULTS: {
|
|
10
|
+
/**
|
|
11
|
+
* Default instance key for shared instances
|
|
12
|
+
*/
|
|
13
|
+
readonly DEFAULT_INSTANCE_KEY: "default";
|
|
14
|
+
/**
|
|
15
|
+
* Maximum getter nesting depth (prevents infinite recursion)
|
|
16
|
+
*/
|
|
17
|
+
readonly MAX_GETTER_DEPTH: 10;
|
|
18
|
+
/**
|
|
19
|
+
* Default cleanup interval for subscriptions (30 seconds)
|
|
20
|
+
*/
|
|
21
|
+
readonly CLEANUP_INTERVAL_MS: 30000;
|
|
22
|
+
/**
|
|
23
|
+
* Cleanup interval for weak reference stage (10 seconds)
|
|
24
|
+
*/
|
|
25
|
+
readonly WEAKREF_CLEANUP_INTERVAL_MS: 10000;
|
|
26
|
+
/**
|
|
27
|
+
* Default maximum subscriptions per container
|
|
28
|
+
*/
|
|
29
|
+
readonly MAX_SUBSCRIPTIONS: 1000;
|
|
30
|
+
/**
|
|
31
|
+
* Maximum subscriptions for high-performance mode
|
|
32
|
+
*/
|
|
33
|
+
readonly MAX_SUBSCRIPTIONS_HIGH_PERF: 10000;
|
|
34
|
+
/**
|
|
35
|
+
* Default timeout for pipeline execution (5 seconds)
|
|
36
|
+
*/
|
|
37
|
+
readonly PIPELINE_TIMEOUT_MS: 5000;
|
|
38
|
+
/**
|
|
39
|
+
* Cleanup interval for high-performance mode (5 seconds)
|
|
40
|
+
*/
|
|
41
|
+
readonly CLEANUP_INTERVAL_HIGH_PERF_MS: 5000;
|
|
42
|
+
/**
|
|
43
|
+
* Maximum number of stages in a pipeline
|
|
44
|
+
*/
|
|
45
|
+
readonly MAX_PIPELINE_STAGES: 30;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Static property names for StateContainer classes
|
|
49
|
+
* Used for feature flags and configuration on bloc classes
|
|
50
|
+
*/
|
|
51
|
+
export declare const BLAC_STATIC_PROPS: {
|
|
52
|
+
/**
|
|
53
|
+
* Mark a bloc as isolated (each component gets its own instance)
|
|
54
|
+
*/
|
|
55
|
+
readonly ISOLATED: "isolated";
|
|
56
|
+
/**
|
|
57
|
+
* Mark a bloc to never be auto-disposed (kept alive permanently)
|
|
58
|
+
*/
|
|
59
|
+
readonly KEEP_ALIVE: "keepAlive";
|
|
60
|
+
/**
|
|
61
|
+
* Exclude a bloc from DevTools reporting (prevents infinite loops)
|
|
62
|
+
*/
|
|
63
|
+
readonly EXCLUDE_FROM_DEVTOOLS: "__excludeFromDevTools";
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* ID generation patterns and constants
|
|
67
|
+
*/
|
|
68
|
+
export declare const BLAC_ID_PATTERNS: {
|
|
69
|
+
/**
|
|
70
|
+
* Prefix for isolated instance keys
|
|
71
|
+
*/
|
|
72
|
+
readonly ISOLATED_PREFIX: "isolated-";
|
|
73
|
+
/**
|
|
74
|
+
* Length of generated ID portion (9 characters from base36)
|
|
75
|
+
*/
|
|
76
|
+
readonly ID_LENGTH: 9;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Standard error message prefix
|
|
80
|
+
*/
|
|
81
|
+
export declare const BLAC_ERROR_PREFIX: "[BlaC]";
|
|
82
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cubit - Simple state container with direct state emission
|
|
3
|
+
*
|
|
4
|
+
* This validates that our StateContainer design can support
|
|
5
|
+
* the simple Cubit pattern from the original BlaC.
|
|
6
|
+
*/
|
|
7
|
+
import { StateContainer } from './StateContainer';
|
|
8
|
+
/**
|
|
9
|
+
* Cubit is a simple state container that allows direct state emission
|
|
10
|
+
*
|
|
11
|
+
* Unlike StateContainer (where emit is protected), Cubit exposes emit and update
|
|
12
|
+
* as public methods to allow direct state management.
|
|
13
|
+
*/
|
|
14
|
+
export declare abstract class Cubit<S> extends StateContainer<S> {
|
|
15
|
+
/**
|
|
16
|
+
* Create a new Cubit
|
|
17
|
+
* @param initialState Initial state value
|
|
18
|
+
*/
|
|
19
|
+
constructor(initialState: S);
|
|
20
|
+
/**
|
|
21
|
+
* Emit a new state (public override of protected parent method)
|
|
22
|
+
*/
|
|
23
|
+
emit(newState: S): void;
|
|
24
|
+
/**
|
|
25
|
+
* Update state using a function (public override of protected parent method)
|
|
26
|
+
*/
|
|
27
|
+
update(updater: (current: S) => S): void;
|
|
28
|
+
/**
|
|
29
|
+
* Patch state with partial updates (shallow merge)
|
|
30
|
+
* Only available when state is an object type
|
|
31
|
+
* Arrow function to maintain correct 'this' binding in React
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* // Update single field
|
|
36
|
+
* this.patch({ count: 5 });
|
|
37
|
+
*
|
|
38
|
+
* // Update multiple fields
|
|
39
|
+
* this.patch({ count: 5, name: 'Updated' });
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
patch: S extends object ? (partial: Partial<S>) => void : never;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Example: Counter Cubit
|
|
46
|
+
*/
|
|
47
|
+
export declare class CounterCubit extends Cubit<number> {
|
|
48
|
+
constructor();
|
|
49
|
+
increment: () => void;
|
|
50
|
+
decrement: () => void;
|
|
51
|
+
reset: () => void;
|
|
52
|
+
addAmount: (amount: number) => void;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Example: Complex State Cubit
|
|
56
|
+
*/
|
|
57
|
+
export interface TodoState {
|
|
58
|
+
todos: Array<{
|
|
59
|
+
id: string;
|
|
60
|
+
text: string;
|
|
61
|
+
done: boolean;
|
|
62
|
+
}>;
|
|
63
|
+
filter: 'all' | 'active' | 'completed';
|
|
64
|
+
isLoading: boolean;
|
|
65
|
+
}
|
|
66
|
+
export declare class TodoCubit extends Cubit<TodoState> {
|
|
67
|
+
static keepAlive: boolean;
|
|
68
|
+
private nextId;
|
|
69
|
+
constructor();
|
|
70
|
+
addTodo: (text: string) => void;
|
|
71
|
+
toggleTodo: (id: string) => void;
|
|
72
|
+
removeTodo: (id: string) => void;
|
|
73
|
+
setFilter: (filter: TodoState["filter"]) => void;
|
|
74
|
+
setLoading: (isLoading: boolean) => void;
|
|
75
|
+
get visibleTodos(): {
|
|
76
|
+
id: string;
|
|
77
|
+
text: string;
|
|
78
|
+
done: boolean;
|
|
79
|
+
}[];
|
|
80
|
+
get activeTodoCount(): number;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=Cubit.d.ts.map
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StateContainer - Clean, minimal state management container
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* - State storage and updates
|
|
6
|
+
* - Change notifications to subscribers
|
|
7
|
+
* - Lifecycle management
|
|
8
|
+
*/
|
|
9
|
+
import { StateContainerRegistry } from './StateContainerRegistry';
|
|
10
|
+
/**
|
|
11
|
+
* Configuration options for StateContainer
|
|
12
|
+
*/
|
|
13
|
+
export interface StateContainerConfig {
|
|
14
|
+
/** Container name for debugging */
|
|
15
|
+
name?: string;
|
|
16
|
+
/** Enable debug logging */
|
|
17
|
+
debug?: boolean;
|
|
18
|
+
/** Custom instance identifier */
|
|
19
|
+
instanceId?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Listener function for state changes
|
|
23
|
+
*/
|
|
24
|
+
type StateListener<S> = (state: S) => void;
|
|
25
|
+
/**
|
|
26
|
+
* Base abstract class for all state containers
|
|
27
|
+
*/
|
|
28
|
+
export declare abstract class StateContainer<S> {
|
|
29
|
+
/**
|
|
30
|
+
* Exclude this class from DevTools reporting
|
|
31
|
+
* Set to true for internal/DevTools-related Blocs to prevent infinite loops
|
|
32
|
+
*/
|
|
33
|
+
static __excludeFromDevTools: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Global registry for lifecycle events and instance management
|
|
36
|
+
*/
|
|
37
|
+
protected static _registry: StateContainerRegistry;
|
|
38
|
+
/**
|
|
39
|
+
* Get the global registry (mainly for testing)
|
|
40
|
+
*/
|
|
41
|
+
static getRegistry(): StateContainerRegistry;
|
|
42
|
+
/**
|
|
43
|
+
* Set a custom registry (mainly for testing)
|
|
44
|
+
*
|
|
45
|
+
* Clears all instances before switching to ensure clean test isolation.
|
|
46
|
+
*/
|
|
47
|
+
static setRegistry(registry: StateContainerRegistry): void;
|
|
48
|
+
/**
|
|
49
|
+
* Register a type as isolated or shared
|
|
50
|
+
*/
|
|
51
|
+
static register<T extends StateContainer<any>>(this: new (...args: any[]) => T, isolated?: boolean): void;
|
|
52
|
+
/**
|
|
53
|
+
* Resolve an instance with ref counting (ownership semantics)
|
|
54
|
+
*
|
|
55
|
+
* Delegates to the global registry for instance management.
|
|
56
|
+
*
|
|
57
|
+
* @param instanceKey - Optional instance key for shared instances
|
|
58
|
+
* @param constructorArgs - Constructor arguments
|
|
59
|
+
* @returns Instance with incremented ref count
|
|
60
|
+
*/
|
|
61
|
+
static resolve<T extends StateContainer<any>>(this: new (...args: any[]) => T, instanceKey?: string, constructorArgs?: any): T;
|
|
62
|
+
/**
|
|
63
|
+
* Get an existing instance without ref counting (borrowing semantics)
|
|
64
|
+
* Delegates to the global registry.
|
|
65
|
+
*/
|
|
66
|
+
static get<T extends StateContainer<any>>(this: new (...args: any[]) => T, instanceKey?: string): T;
|
|
67
|
+
/**
|
|
68
|
+
* Safely get an existing instance (borrowing semantics with error handling)
|
|
69
|
+
* Delegates to the global registry.
|
|
70
|
+
*/
|
|
71
|
+
static getSafe<T extends StateContainer<any>>(this: new (...args: any[]) => T, instanceKey?: string): {
|
|
72
|
+
error: Error;
|
|
73
|
+
instance: null;
|
|
74
|
+
} | {
|
|
75
|
+
error: null;
|
|
76
|
+
instance: T;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Connect to an instance with borrowing semantics (for B2B communication)
|
|
80
|
+
* Gets existing instance OR creates it if it doesn't exist, without incrementing ref count.
|
|
81
|
+
* Tracks cross-bloc dependency for reactive updates.
|
|
82
|
+
*
|
|
83
|
+
* Use this in bloc-to-bloc communication when you need to ensure an instance exists
|
|
84
|
+
* but don't want to claim ownership (no ref count increment).
|
|
85
|
+
*
|
|
86
|
+
* Delegates to the global registry.
|
|
87
|
+
*
|
|
88
|
+
* @param instanceKey - Optional instance key (defaults to 'default')
|
|
89
|
+
* @param constructorArgs - Constructor arguments (only used if creating new instance)
|
|
90
|
+
* @returns The bloc instance
|
|
91
|
+
*/
|
|
92
|
+
static connect<T extends StateContainer<any>>(this: new (...args: any[]) => T, instanceKey?: string, constructorArgs?: any): T;
|
|
93
|
+
/**
|
|
94
|
+
* Release a reference to an instance
|
|
95
|
+
* Delegates to the global registry.
|
|
96
|
+
*/
|
|
97
|
+
static release<T extends StateContainer<any>>(this: new (...args: any[]) => T, instanceKey?: string, forceDispose?: boolean): void;
|
|
98
|
+
/**
|
|
99
|
+
* Get all instances of this type
|
|
100
|
+
* Delegates to the global registry.
|
|
101
|
+
*/
|
|
102
|
+
static getAll<T extends StateContainer<any>>(this: new (...args: any[]) => T): T[];
|
|
103
|
+
/**
|
|
104
|
+
* Safely iterate over all instances of this type
|
|
105
|
+
* Delegates to the global registry.
|
|
106
|
+
*/
|
|
107
|
+
static forEach<T extends StateContainer<any>>(this: new (...args: any[]) => T, callback: (instance: T) => void): void;
|
|
108
|
+
/**
|
|
109
|
+
* Clear all instances of this type
|
|
110
|
+
* Delegates to the global registry.
|
|
111
|
+
*/
|
|
112
|
+
static clear<T extends StateContainer<any>>(this: new (...args: any[]) => T): void;
|
|
113
|
+
/**
|
|
114
|
+
* Clear all instances from all types (for testing)
|
|
115
|
+
* Delegates to the global registry.
|
|
116
|
+
*/
|
|
117
|
+
static clearAllInstances(): void;
|
|
118
|
+
/**
|
|
119
|
+
* Get registry statistics (for debugging)
|
|
120
|
+
* Delegates to the global registry.
|
|
121
|
+
*/
|
|
122
|
+
static getStats(): {
|
|
123
|
+
registeredTypes: number;
|
|
124
|
+
totalInstances: number;
|
|
125
|
+
typeBreakdown: Record<string, number>;
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Get reference count for an instance
|
|
129
|
+
* Delegates to the global registry.
|
|
130
|
+
*/
|
|
131
|
+
static getRefCount<T extends StateContainer<any>>(this: new (...args: any[]) => T, instanceKey?: string): number;
|
|
132
|
+
/**
|
|
133
|
+
* Check if an instance exists
|
|
134
|
+
* Delegates to the global registry.
|
|
135
|
+
*/
|
|
136
|
+
static hasInstance<T extends StateContainer<any>>(this: new (...args: any[]) => T, instanceKey?: string): boolean;
|
|
137
|
+
private _state;
|
|
138
|
+
private readonly listeners;
|
|
139
|
+
private _disposed;
|
|
140
|
+
private config;
|
|
141
|
+
name: string;
|
|
142
|
+
debug: boolean;
|
|
143
|
+
instanceId: string;
|
|
144
|
+
createdAt: number;
|
|
145
|
+
/**
|
|
146
|
+
* Create a new StateContainer
|
|
147
|
+
*/
|
|
148
|
+
constructor(initialState: S);
|
|
149
|
+
initConfig(config: StateContainerConfig): void;
|
|
150
|
+
/**
|
|
151
|
+
* Get the current state
|
|
152
|
+
*/
|
|
153
|
+
get state(): S;
|
|
154
|
+
/**
|
|
155
|
+
* Check if disposed
|
|
156
|
+
*/
|
|
157
|
+
get isDisposed(): boolean;
|
|
158
|
+
/**
|
|
159
|
+
* Subscribe to state changes
|
|
160
|
+
* @returns Unsubscribe function
|
|
161
|
+
*/
|
|
162
|
+
subscribe(listener: StateListener<S>): () => void;
|
|
163
|
+
/**
|
|
164
|
+
* Dispose the container
|
|
165
|
+
*/
|
|
166
|
+
dispose(): void;
|
|
167
|
+
/**
|
|
168
|
+
* Emit a new state (with change detection)
|
|
169
|
+
*/
|
|
170
|
+
protected emit(newState: S): void;
|
|
171
|
+
/**
|
|
172
|
+
* Enable stack trace capture in development
|
|
173
|
+
* Defaults to true, but can be disabled to improve performance
|
|
174
|
+
*/
|
|
175
|
+
static enableStackTrace: boolean;
|
|
176
|
+
/**
|
|
177
|
+
* Capture stack trace for debugging
|
|
178
|
+
* Can be overridden to disable in production
|
|
179
|
+
*/
|
|
180
|
+
private captureStackTrace;
|
|
181
|
+
/**
|
|
182
|
+
* Format a single stack trace line for better readability
|
|
183
|
+
* Removes URL prefixes, query params, and cleans up the output
|
|
184
|
+
*/
|
|
185
|
+
private formatStackLine;
|
|
186
|
+
/**
|
|
187
|
+
* Clean up file path by removing URL prefixes and query params
|
|
188
|
+
*/
|
|
189
|
+
private cleanFilePath;
|
|
190
|
+
lastUpdateTimestamp: number;
|
|
191
|
+
/**
|
|
192
|
+
* Update state using a function
|
|
193
|
+
*/
|
|
194
|
+
protected update(updater: (current: S) => S): void;
|
|
195
|
+
/**
|
|
196
|
+
* Optional disposal hook for subclasses
|
|
197
|
+
*/
|
|
198
|
+
protected onDispose?(): void;
|
|
199
|
+
/**
|
|
200
|
+
* Optional state change hook for subclasses
|
|
201
|
+
*/
|
|
202
|
+
protected onStateChange?(newState: S, previousState: S): void;
|
|
203
|
+
}
|
|
204
|
+
export {};
|
|
205
|
+
//# sourceMappingURL=StateContainer.d.ts.map
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StateContainerRegistry - Centralized instance and lifecycle management
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* - Instance storage and management (WeakMap per constructor)
|
|
6
|
+
* - Type registration and tracking
|
|
7
|
+
* - Lifecycle event notifications (plugin system)
|
|
8
|
+
* - Global operations (clearAllInstances)
|
|
9
|
+
*/
|
|
10
|
+
import type { StateContainer } from './StateContainer';
|
|
11
|
+
import type { Vertex } from './Vertex';
|
|
12
|
+
/**
|
|
13
|
+
* Internal entry for instance storage
|
|
14
|
+
* Each entry tracks an instance and its reference count
|
|
15
|
+
*/
|
|
16
|
+
export interface InstanceEntry<T = any> {
|
|
17
|
+
instance: T;
|
|
18
|
+
refCount: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Lifecycle events that can be observed
|
|
22
|
+
*/
|
|
23
|
+
export type LifecycleEvent = 'created' | 'stateChanged' | 'eventAdded' | 'disposed';
|
|
24
|
+
/**
|
|
25
|
+
* Listener function types for each lifecycle event
|
|
26
|
+
*/
|
|
27
|
+
export type LifecycleListener<E extends LifecycleEvent> = E extends 'created' ? (container: StateContainer<any>) => void : E extends 'stateChanged' ? (container: StateContainer<any>, previousState: any, currentState: any, callstack?: string) => void : E extends 'eventAdded' ? (container: Vertex<any, any>, event: any) => void : E extends 'disposed' ? (container: StateContainer<any>) => void : never;
|
|
28
|
+
/**
|
|
29
|
+
* Registry for coordinating StateContainer lifecycle and managing instances
|
|
30
|
+
*
|
|
31
|
+
* Centralizes all instance management using WeakMap to ensure proper isolation.
|
|
32
|
+
*/
|
|
33
|
+
export declare class StateContainerRegistry {
|
|
34
|
+
/**
|
|
35
|
+
* Global storage for all instance Maps, keyed by constructor
|
|
36
|
+
*
|
|
37
|
+
* IMPORTANT: JavaScript/TypeScript static properties are inherited by reference,
|
|
38
|
+
* meaning all subclasses would share the same Map. To ensure each subclass has
|
|
39
|
+
* its own instance storage, we use a WeakMap keyed by the constructor function.
|
|
40
|
+
*
|
|
41
|
+
* This approach guarantees:
|
|
42
|
+
* - CounterBloc instances are separate from UserBloc instances
|
|
43
|
+
* - Each class owns and manages its own instances
|
|
44
|
+
* - Automatic garbage collection when classes are no longer referenced
|
|
45
|
+
*/
|
|
46
|
+
private readonly instancesByConstructor;
|
|
47
|
+
/**
|
|
48
|
+
* Strong Set for tracking all registered types
|
|
49
|
+
* Used for clearAllInstances() and getStats()
|
|
50
|
+
*/
|
|
51
|
+
private readonly types;
|
|
52
|
+
/**
|
|
53
|
+
* Type configurations (isolated flag)
|
|
54
|
+
*/
|
|
55
|
+
private readonly typeConfigs;
|
|
56
|
+
/**
|
|
57
|
+
* Lifecycle event listeners
|
|
58
|
+
*/
|
|
59
|
+
private readonly listeners;
|
|
60
|
+
/**
|
|
61
|
+
* Register a type for tracking
|
|
62
|
+
* Called automatically on first instance creation
|
|
63
|
+
*/
|
|
64
|
+
registerType<T extends StateContainer<any>>(constructor: new (...args: any[]) => T): void;
|
|
65
|
+
/**
|
|
66
|
+
* Register a type with isolation mode (explicit registration)
|
|
67
|
+
*/
|
|
68
|
+
register<T extends StateContainer<any>>(constructor: new (...args: any[]) => T, isolated?: boolean): void;
|
|
69
|
+
/**
|
|
70
|
+
* Get the instances Map for a specific class
|
|
71
|
+
* Creates a new Map on first access.
|
|
72
|
+
*/
|
|
73
|
+
private ensureInstancesMap;
|
|
74
|
+
/**
|
|
75
|
+
* Get the instances Map for a specific class (public API for stats/debugging)
|
|
76
|
+
*/
|
|
77
|
+
getInstancesMap<T extends StateContainer<any>>(Type: new (...args: any[]) => T): Map<string, InstanceEntry>;
|
|
78
|
+
/**
|
|
79
|
+
* Resolve an instance with ref counting (ownership semantics)
|
|
80
|
+
*/
|
|
81
|
+
resolve<T extends StateContainer<any>>(Type: new (...args: any[]) => T, instanceKey?: string, constructorArgs?: any): T;
|
|
82
|
+
/**
|
|
83
|
+
* Get an existing instance without ref counting (borrowing semantics)
|
|
84
|
+
* @throws Error if instance doesn't exist
|
|
85
|
+
*/
|
|
86
|
+
get<T extends StateContainer<any>>(Type: new (...args: any[]) => T, instanceKey?: string): T;
|
|
87
|
+
/**
|
|
88
|
+
* Safely get an existing instance (borrowing semantics with error handling)
|
|
89
|
+
* Returns discriminated union for type-safe conditional access
|
|
90
|
+
*/
|
|
91
|
+
getSafe<T extends StateContainer<any>>(Type: new (...args: any[]) => T, instanceKey?: string): {
|
|
92
|
+
error: Error;
|
|
93
|
+
instance: null;
|
|
94
|
+
} | {
|
|
95
|
+
error: null;
|
|
96
|
+
instance: T;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Connect to an instance with borrowing semantics (for B2B communication)
|
|
100
|
+
* Gets existing instance OR creates it if it doesn't exist, without incrementing ref count.
|
|
101
|
+
* Tracks cross-bloc dependency for reactive updates.
|
|
102
|
+
*
|
|
103
|
+
* Use this in bloc-to-bloc communication when you need to ensure an instance exists
|
|
104
|
+
* but don't want to claim ownership (no ref count increment).
|
|
105
|
+
*
|
|
106
|
+
* @param Type - The bloc class constructor
|
|
107
|
+
* @param instanceKey - Optional instance key (defaults to 'default')
|
|
108
|
+
* @param constructorArgs - Constructor arguments (only used if creating new instance)
|
|
109
|
+
* @returns The bloc instance
|
|
110
|
+
*/
|
|
111
|
+
connect<T extends StateContainer<any>>(Type: new (...args: any[]) => T, instanceKey?: string, constructorArgs?: any): T;
|
|
112
|
+
/**
|
|
113
|
+
* Release a reference to an instance
|
|
114
|
+
*/
|
|
115
|
+
release<T extends StateContainer<any>>(Type: new (...args: any[]) => T, instanceKey?: string, forceDispose?: boolean): void;
|
|
116
|
+
/**
|
|
117
|
+
* Get all instances of a specific type
|
|
118
|
+
*/
|
|
119
|
+
getAll<T extends StateContainer<any>>(Type: new (...args: any[]) => T): T[];
|
|
120
|
+
/**
|
|
121
|
+
* Safely iterate over all instances of a type
|
|
122
|
+
*/
|
|
123
|
+
forEach<T extends StateContainer<any>>(Type: new (...args: any[]) => T, callback: (instance: T) => void): void;
|
|
124
|
+
/**
|
|
125
|
+
* Clear all instances of a specific type
|
|
126
|
+
*/
|
|
127
|
+
clear<T extends StateContainer<any>>(Type: new (...args: any[]) => T): void;
|
|
128
|
+
/**
|
|
129
|
+
* Get reference count for an instance
|
|
130
|
+
*/
|
|
131
|
+
getRefCount<T extends StateContainer<any>>(Type: new (...args: any[]) => T, instanceKey?: string): number;
|
|
132
|
+
/**
|
|
133
|
+
* Check if an instance exists
|
|
134
|
+
*/
|
|
135
|
+
hasInstance<T extends StateContainer<any>>(Type: new (...args: any[]) => T, instanceKey?: string): boolean;
|
|
136
|
+
/**
|
|
137
|
+
* Clear all instances from all types (for testing)
|
|
138
|
+
*
|
|
139
|
+
* Iterates all registered types and clears their instances.
|
|
140
|
+
* Also clears type tracking to reset the registry state.
|
|
141
|
+
*/
|
|
142
|
+
clearAll(): void;
|
|
143
|
+
/**
|
|
144
|
+
* Get registry statistics (for debugging)
|
|
145
|
+
*/
|
|
146
|
+
getStats(): {
|
|
147
|
+
registeredTypes: number;
|
|
148
|
+
totalInstances: number;
|
|
149
|
+
typeBreakdown: Record<string, number>;
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Get all registered types (for plugin system)
|
|
153
|
+
*/
|
|
154
|
+
getTypes(): Array<new (...args: any[]) => StateContainer<any>>;
|
|
155
|
+
/**
|
|
156
|
+
* Subscribe to lifecycle events
|
|
157
|
+
* @param event - The lifecycle event to listen for
|
|
158
|
+
* @param listener - The listener function to call when the event occurs
|
|
159
|
+
* @returns Unsubscribe function
|
|
160
|
+
*/
|
|
161
|
+
on<E extends LifecycleEvent>(event: E, listener: LifecycleListener<E>): () => void;
|
|
162
|
+
/**
|
|
163
|
+
* Emit lifecycle event to all listeners
|
|
164
|
+
* @internal - Called by StateContainer/Vertex lifecycle methods
|
|
165
|
+
*/
|
|
166
|
+
emit(event: LifecycleEvent, ...args: any[]): void;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Global default registry instance
|
|
170
|
+
*/
|
|
171
|
+
export declare const globalRegistry: StateContainerRegistry;
|
|
172
|
+
/**
|
|
173
|
+
* Get the global plugin manager
|
|
174
|
+
*/
|
|
175
|
+
export declare function getPluginManager(): any;
|
|
176
|
+
//# sourceMappingURL=StateContainerRegistry.d.ts.map
|