@blac/core 2.0.10 → 2.0.11

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.
Files changed (2) hide show
  1. package/README.md +59 -83
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,76 +1,68 @@
1
1
  # @blac/core
2
2
 
3
- Core state management primitives for BlaC: state containers, registry, plugins, and tracking utilities.
3
+ Core state management primitives for BlaC — state containers, registry, plugins, and tracking utilities.
4
4
 
5
- **[Full documentation](https://jsnanigans.github.io/blac/guide/introduction)**
5
+ **[Documentation](https://blac-docs.pages.dev/guide/introduction)** · **[npm](https://www.npmjs.com/package/@blac/core)**
6
6
 
7
7
  ## Installation
8
8
 
9
9
  ```bash
10
- npm install @blac/core
11
- # or
12
10
  pnpm add @blac/core
13
- # or
14
- yarn add @blac/core
15
11
  ```
16
12
 
17
- ## Core Concepts
13
+ ## State Containers
18
14
 
19
- ### StateContainer
15
+ ### Cubit
20
16
 
21
- `StateContainer` is the abstract base class. It provides state storage, subscriptions, lifecycle events, and registry integration.
17
+ The primary building block. Extends `StateContainer` with public `emit`, `update`, and `patch` methods.
22
18
 
23
19
  ```ts
24
- import { StateContainer } from '@blac/core';
20
+ import { Cubit } from '@blac/core';
25
21
 
26
- class CounterContainer extends StateContainer<{ count: number }> {
22
+ class CounterCubit extends Cubit<{ count: number }> {
27
23
  constructor() {
28
24
  super({ count: 0 });
29
25
  }
30
26
 
31
- increment() {
32
- this.update((state) => ({ count: state.count + 1 }));
33
- }
27
+ increment = () => this.emit({ count: this.state.count + 1 });
28
+ decrement = () => this.update((s) => ({ count: s.count - 1 }));
29
+ reset = () => this.patch({ count: 0 });
34
30
  }
35
31
  ```
36
32
 
37
- Key public API:
38
-
39
- - `state` (readonly)
40
- - `subscribe(listener)` -> `unsubscribe`
41
- - `dispose()`
42
- - `isDisposed`, `name`, `debug`, `instanceId`, `createdAt`, `lastUpdateTimestamp`
33
+ - `emit(newState)` — replace the entire state
34
+ - `update(fn)` — derive new state from current
35
+ - `patch(partial)` — shallow merge (object state only)
43
36
 
44
- Protected API for subclasses:
45
-
46
- - `emit(newState)`
47
- - `update(fn)`
48
- - `onSystemEvent(event, handler)` for `stateChanged` and `dispose`
49
- - `depend(BlocClass, instanceKey?)` for cross-bloc dependencies
50
-
51
- ### Cubit
37
+ ### StateContainer
52
38
 
53
- `Cubit` extends `StateContainer` with public mutation methods.
39
+ Abstract base class. Use this when you want `emit`/`update` to be protected (not callable from outside).
54
40
 
55
41
  ```ts
56
- import { Cubit } from '@blac/core';
42
+ import { StateContainer } from '@blac/core';
57
43
 
58
- class CounterCubit extends Cubit<{ count: number }> {
44
+ class AuthContainer extends StateContainer<{ token: string | null }> {
59
45
  constructor() {
60
- super({ count: 0 });
46
+ super({ token: null });
61
47
  }
62
48
 
63
- increment = () => this.emit({ count: this.state.count + 1 });
64
- decrement = () => this.update((state) => ({ count: state.count - 1 }));
65
- reset = () => this.patch({ count: 0 });
49
+ login(token: string) {
50
+ this.emit({ token });
51
+ }
52
+
53
+ logout() {
54
+ this.emit({ token: null });
55
+ }
66
56
  }
67
57
  ```
68
58
 
69
- `patch()` performs a shallow merge for object state and is only available when `S extends object`.
59
+ **Public API:** `state`, `subscribe(listener)`, `dispose()`, `isDisposed`, `name`, `instanceId`, `createdAt`, `lastUpdateTimestamp`
70
60
 
71
- ## Registry API
61
+ **Protected API:** `emit(state)`, `update(fn)`, `onSystemEvent(event, handler)`, `depend(BlocClass, instanceKey?)`
72
62
 
73
- The registry manages instance lifecycles and ref counting.
63
+ ## Registry
64
+
65
+ Manages instance lifecycles and ref counting.
74
66
 
75
67
  ```ts
76
68
  import {
@@ -81,32 +73,17 @@ import {
81
73
  release,
82
74
  hasInstance,
83
75
  getRefCount,
84
- getAll,
85
- forEach,
86
- clear,
87
- clearAll,
88
76
  } from '@blac/core';
89
77
 
90
- const counter = acquire(CounterCubit); // increments ref count
91
-
92
- const shared = ensure(CounterCubit); // no ref count increment
93
- const existing = borrow(CounterCubit); // no create, no ref count
94
- const maybe = borrowSafe(CounterCubit); // { error, instance }
78
+ const counter = acquire(CounterCubit); // create or reuse, increment ref count
79
+ const shared = ensure(CounterCubit); // create or reuse, no ref count change
80
+ const existing = borrow(CounterCubit); // get existing, throws if missing
81
+ const maybe = borrowSafe(CounterCubit); // get existing, returns { error, instance }
95
82
 
96
- release(CounterCubit); // decrements ref count, auto-dispose at 0 unless keepAlive
97
-
98
- if (hasInstance(CounterCubit)) {
99
- console.log(getRefCount(CounterCubit));
100
- }
101
-
102
- forEach(CounterCubit, (inst) => console.log(inst.state));
103
- clear(CounterCubit);
104
- clearAll();
83
+ release(CounterCubit); // decrement ref count, auto-dispose at 0 (unless keepAlive)
105
84
  ```
106
85
 
107
- ## Decorators
108
-
109
- Configure container behavior with `@blac`.
86
+ ## Configuration
110
87
 
111
88
  ```ts
112
89
  import { Cubit, blac } from '@blac/core';
@@ -118,29 +95,27 @@ class AuthCubit extends Cubit<AuthState> {}
118
95
  class InternalCubit extends Cubit<State> {}
119
96
  ```
120
97
 
121
- `BlacOptions` is a union type, so only one option can be specified at a time.
98
+ ## Watch
122
99
 
123
- ## Watch and Tracking
124
-
125
- ### watch
100
+ Observe state changes outside of a UI framework.
126
101
 
127
102
  ```ts
128
103
  import { watch, instance } from '@blac/core';
129
104
 
130
105
  const stop = watch(CounterCubit, (counter) => {
131
106
  console.log(counter.state.count);
132
-
133
- if (counter.state.count >= 10) {
134
- return watch.STOP; // stop from inside the callback
135
- }
107
+ if (counter.state.count >= 10) return watch.STOP;
136
108
  });
137
109
 
138
- const stopSpecific = watch(instance(CounterCubit, 'counter-1'), (counter) => {
139
- console.log(counter.state.count);
110
+ // Watch a specific named instance
111
+ const stop2 = watch(instance(CounterCubit, 'counter-1'), (c) => {
112
+ console.log(c.state.count);
140
113
  });
141
114
  ```
142
115
 
143
- ### tracked
116
+ ## Tracked
117
+
118
+ Run a function and capture which blocs/state it accessed.
144
119
 
145
120
  ```ts
146
121
  import { tracked } from '@blac/core';
@@ -156,27 +131,28 @@ const { result, dependencies } = tracked(() => {
156
131
  ```ts
157
132
  import { getPluginManager, type BlacPlugin } from '@blac/core';
158
133
 
159
- const loggingPlugin: BlacPlugin = {
160
- name: 'logging',
134
+ const myPlugin: BlacPlugin = {
135
+ name: 'my-plugin',
161
136
  version: '1.0.0',
162
- onStateChanged(instance, previousState, currentState, callstack) {
163
- console.log(instance.constructor.name, previousState, currentState);
164
- if (callstack) console.log(callstack);
137
+ onStateChanged(instance, previousState, currentState) {
138
+ console.log(instance.constructor.name, previousState, '→', currentState);
165
139
  },
166
140
  };
167
141
 
168
- getPluginManager().install(loggingPlugin, {
169
- enabled: true,
170
- environment: 'development',
171
- });
142
+ getPluginManager().install(myPlugin, { environment: 'development' });
172
143
  ```
173
144
 
174
145
  ## Subpath Exports
175
146
 
176
- - `@blac/core/watch` -> `watch`, `instance`, `tracked` utilities
177
- - `@blac/core/tracking` -> dependency tracking utilities for framework adapters
178
- - `@blac/core/plugins` -> plugin system exports
179
- - `@blac/core/debug` -> advanced registry introspection helpers
147
+ | Export | Contents |
148
+ | --------------------- | ------------------------------------------------------ |
149
+ | `@blac/core` | All core classes, registry, decorators, watch, tracked |
150
+ | `@blac/core/watch` | `watch`, `instance`, `tracked` |
151
+ | `@blac/core/tracking` | Dependency tracking internals for framework adapters |
152
+ | `@blac/core/plugins` | Plugin system types and utilities |
153
+ | `@blac/core/debug` | Registry introspection helpers |
154
+ | `@blac/core/testing` | Test utilities |
155
+ | `@blac/core/types` | Type-only exports |
180
156
 
181
157
  ## License
182
158
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blac/core",
3
- "version": "2.0.10",
3
+ "version": "2.0.11",
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",