@violetflux/kerros 0.3.4 → 0.3.5

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.de.md CHANGED
@@ -90,7 +90,7 @@ Der zurückgegebene Store Hook verwendet ohne Argument automatisches Tracking. E
90
90
 
91
91
  Der dritte Getter liest außerhalb von React den zuletzt committeten Provider. Mit `scope?: string | number | symbol` am Provider wählt er die neueste exakt passende Instanz. Er abonniert keine Updates und wirft ohne verfügbaren Provider einen Fehler.
92
92
 
93
- React-Elemente und Portale sind automatisch atomar. `useRef()` und `createRef()` können direkt zurückgegeben werden; `ref(value)` ist nur für Proxy-inkompatible Werte oder strikte Identität gedacht.
93
+ React-Elemente und Portale sind automatisch atomar. `useRef()` und `createRef()` können direkt zurückgegeben werden; `ref(value)` ist nur für Proxy-inkompatible Werte oder strikte Identität gedacht. `null` und `undefined` werden unverändert und mit demselben Typ zurückgegeben. Optionale Objekte können daher ohne Nullprüfung direkt an `ref(value)` übergeben werden.
94
94
 
95
95
  `bindStore` ist eine fortgeschrittene Integration ausschließlich für einen bestehenden Headless External Store. Für normalen Hook-Zustand bleibt `createStore` die richtige Wahl. Der Context enthält nur die ursprüngliche Store-Instanz; Verbraucher verwenden `getSnapshot` und `subscribe` direkt.
96
96
 
package/README.es.md CHANGED
@@ -90,7 +90,7 @@ Sin argumentos, el Hook devuelto usa seguimiento automático. Los selectores de
90
90
 
91
91
  El tercer getter lee fuera de React el último Provider confirmado. Con `scope?: string | number | symbol` en el Provider selecciona la instancia más reciente que coincida exactamente. No se suscribe y lanza un error si no hay un Provider disponible.
92
92
 
93
- Los elementos y portales de React son atómicos automáticamente. `useRef()` y `createRef()` se pueden devolver directamente; `ref(value)` se reserva para valores incompatibles con Proxy o identidad estricta.
93
+ Los elementos y portales de React son atómicos automáticamente. `useRef()` y `createRef()` se pueden devolver directamente; `ref(value)` se reserva para valores incompatibles con Proxy o identidad estricta. `null` y `undefined` se devuelven sin cambios y conservan su tipo, por lo que los objetos opcionales pueden pasarse directamente a `ref(value)` sin comprobar si son nulos.
94
94
 
95
95
  `bindStore` es una integración avanzada solo para un Headless External Store existente. Para el estado normal de Hooks, usa `createStore`. El Context solo contiene la instancia original; los consumidores utilizan directamente `getSnapshot` y `subscribe`.
96
96
 
package/README.fr.md CHANGED
@@ -90,7 +90,7 @@ Sans argument, le Hook retourné active le suivi automatique. Les sélecteurs d'
90
90
 
91
91
  Le troisième getter lit hors de React le dernier Provider validé par un commit. Avec `scope?: string | number | symbol` sur le Provider, il choisit la dernière instance qui correspond exactement. Il ne s'abonne pas et lève une erreur sans Provider disponible.
92
92
 
93
- Les éléments et portails React sont automatiquement atomiques. `useRef()` et `createRef()` peuvent être retournés directement ; `ref(value)` est réservé aux valeurs incompatibles avec Proxy ou à l'identité stricte.
93
+ Les éléments et portails React sont automatiquement atomiques. `useRef()` et `createRef()` peuvent être retournés directement ; `ref(value)` est réservé aux valeurs incompatibles avec Proxy ou à l'identité stricte. `null` et `undefined` sont renvoyés tels quels, avec leur type préservé. Les objets optionnels peuvent donc être passés directement à `ref(value)` sans vérification de nullité.
94
94
 
95
95
  `bindStore` est une intégration avancée réservée à un Headless External Store existant. Pour un état Hook ordinaire, utilisez `createStore`. Le Context ne contient que l'instance d'origine ; les consommateurs utilisent directement `getSnapshot` et `subscribe`.
96
96
 
package/README.ja.md CHANGED
@@ -91,7 +91,7 @@ const [useStream, StreamProvider] = bindStore<Stream>('Stream')
91
91
 
92
92
  3 番目の getter は React 外から最後にコミットされた Provider を読み取ります。Provider の `scope?: string | number | symbol` を渡すと完全一致する最新インスタンスを選べます。getter は購読せず、利用可能な Provider がなければエラーを投げます。
93
93
 
94
- React Element と Portal は自動的に原子的な値になります。`useRef()` と `createRef()` はそのまま返せます。`ref(value)` は Proxy 非互換の値や厳密な同一性が必要な場合だけ使います。
94
+ React Element と Portal は自動的に原子的な値になります。`useRef()` と `createRef()` はそのまま返せます。`ref(value)` は Proxy 非互換の値や厳密な同一性が必要な場合だけ使います。 `null` と `undefined` は型を保ったまま返されるため、省略可能なオブジェクトも null チェックなしで `ref(value)` に直接渡せます。
95
95
 
96
96
  高度な連携として、既存の Headless External Store にだけ `bindStore` を使います。通常の Hook 状態には `createStore` を使ってください。Context は元の Store インスタンスだけを保持し、コンシューマーは `getSnapshot` と `subscribe` を直接利用します。
97
97
 
package/README.ko.md CHANGED
@@ -91,7 +91,7 @@ const [useStream, StreamProvider] = bindStore<Stream>('Stream')
91
91
 
92
92
  세 번째 getter는 React 밖에서 마지막으로 커밋된 Provider를 읽습니다. Provider의 `scope?: string | number | symbol`을 전달하면 정확히 일치하는 최신 인스턴스를 선택합니다. getter는 구독하지 않으며 사용 가능한 Provider가 없으면 오류를 던집니다.
93
93
 
94
- React Element와 Portal은 자동으로 원자 값이 됩니다. `useRef()`와 `createRef()`는 그대로 반환할 수 있으며 `ref(value)`는 Proxy 비호환 값이나 엄격한 동일성이 필요할 때만 사용합니다.
94
+ React Element와 Portal은 자동으로 원자 값이 됩니다. `useRef()`와 `createRef()`는 그대로 반환할 수 있으며 `ref(value)`는 Proxy 비호환 값이나 엄격한 동일성이 필요할 때만 사용합니다. `null`과 `undefined`는 타입을 유지한 채 그대로 반환되므로 선택적 객체도 null 검사 없이 `ref(value)`에 직접 전달할 수 있습니다.
95
95
 
96
96
  고급 통합이 필요한 기존 Headless External Store에만 `bindStore`를 사용하세요. 일반 Hook 상태에는 `createStore`를 사용합니다. Context는 원래 Store 인스턴스만 보관하고 소비자는 `getSnapshot`과 `subscribe`를 직접 사용합니다.
97
97
 
package/README.md CHANGED
@@ -154,7 +154,7 @@ const { count, setCount } = useCounter()
154
154
 
155
155
  Primitive snapshots use `Object.is`. `Map`, `Set`, class instances, and other non-plain objects are treated as atomic references. Store and external Store snapshots must be immutable: publish a new reference for every observable change.
156
156
 
157
- React elements and portals are atomic automatically. Standard `useRef()` and `createRef()` containers can be returned directly in React 17, 18, and 19. Use `ref(value)` only for Proxy-intolerant third-party objects or strict identity; internal mutation of an atomic value is not reactive.
157
+ React elements and portals are atomic automatically. Standard `useRef()` and `createRef()` containers can be returned directly in React 17, 18, and 19. Use `ref(value)` only for Proxy-intolerant third-party objects or strict identity; internal mutation of an atomic value is not reactive. `null` and `undefined` pass through unchanged, with their types preserved, so optional objects can be passed directly as `ref(value)` without a null check.
158
158
 
159
159
  The selector-free result is the component's read-only tracked snapshot. You may destructure it, keep it in a render-local variable, or pass it to a synchronously rendered child. Do not mutate it or retain it in state, refs, module variables, or long-lived caches as a live state object; spread, rest destructuring, enumeration, and serialization create broad subscriptions. Reactive Effects should read values during render and declare correct dependencies. Use `useInstance()` only for imperative latest-state reads that do not drive rendering, and never expose an Effect Event as a public Store action.
160
160
 
@@ -257,7 +257,7 @@ function createStore<TStore, TProps = Record<never, never>>(
257
257
  ### `ref` (identity escape hatch)
258
258
 
259
259
  ```ts
260
- function ref<T extends object>(value: T): T
260
+ function ref<T extends object | null | undefined>(value: T): T
261
261
  ```
262
262
 
263
263
  Marks an object as atomic and returns the exact same identity. Standard React refs do not need this helper.
package/README.zh-CN.md CHANGED
@@ -146,7 +146,7 @@ const { count, setCount } = useCounter()
146
146
 
147
147
  基础类型快照使用 `Object.is`。`Map`、`Set`、类实例及其他非普通对象按整体引用处理。Store 和 External Store 快照必须保持不可变:每次可观察变化都发布新引用。
148
148
 
149
- React Element 和 Portal 会自动作为原子值处理。React 17、18、19 的标准 `useRef()`、`createRef()` 容器可以直接返回。只有第三方对象不能接受 Proxy,或者必须保留严格身份时才使用 `ref(value)`;原子值的内部原地修改不是响应式更新。
149
+ React Element 和 Portal 会自动作为原子值处理。React 17、18、19 的标准 `useRef()`、`createRef()` 容器可以直接返回。只有第三方对象不能接受 Proxy,或者必须保留严格身份时才使用 `ref(value)`;原子值的内部原地修改不是响应式更新。 `null` 和 `undefined` 会原样返回并保留类型,因此可选对象可以直接传给 `ref(value)`,无需在调用处判空。
150
150
 
151
151
  无 selector 的结果是当前组件的只读追踪快照,可以直接解构、保存在渲染局部变量中,或传给同步渲染的子组件继续读取。不要修改快照,也不要把它保存到 state、ref、模块变量或长期缓存后当作实时状态源;展开、rest 解构、枚举和序列化会形成宽泛订阅。响应式 Effect 应在渲染期间读取值并声明正确依赖;只有不参与渲染、需要执行时读取最新状态的命令式逻辑才使用 `useInstance()`。也不要把 Effect Event 暴露成公共 Store action。
152
152
 
@@ -249,7 +249,7 @@ function createStore<TStore, TProps = Record<never, never>>(
249
249
  ### `ref`(身份逃生口)
250
250
 
251
251
  ```ts
252
- function ref<T extends object>(value: T): T
252
+ function ref<T extends object | null | undefined>(value: T): T
253
253
  ```
254
254
 
255
255
  把对象标记为原子值并返回完全相同的身份。标准 React ref 不需要这个辅助函数。
package/dist/index.cjs CHANGED
@@ -224,9 +224,9 @@ function isShallowComparable(value) {
224
224
  }
225
225
  //#endregion
226
226
  //#region src/index.tsx
227
- /** Preserve an exact object identity and compare it as one atomic Store value */
227
+ /** 将对象标记为原子值并保留原始身份,空值直接透传 */
228
228
  function ref(value) {
229
- markToTrack(value, false);
229
+ if (value !== null && value !== void 0) markToTrack(value, false);
230
230
  return value;
231
231
  }
232
232
  const useStoreLayoutEffect = typeof window === "undefined" ? react.useEffect : react.useLayoutEffect;
package/dist/index.d.cts CHANGED
@@ -58,8 +58,8 @@ interface ExternalStore<TSnapshot> {
58
58
  type ExternalStoreSnapshot<TStore> = TStore extends ExternalStore<infer TSnapshot> ? TSnapshot : never;
59
59
  /** React bindings created for an existing external Store type */
60
60
  type StoreBinding<TStore extends ExternalStore<TSnapshot>, TSnapshot = ExternalStoreSnapshot<TStore>> = readonly [StoreHook<TSnapshot>, ExternalStoreProvider<TStore>, StoreInstanceHook<TStore>];
61
- /** Preserve an exact object identity and compare it as one atomic Store value */
62
- declare function ref<T extends object>(value: T): T;
61
+ /** 将对象标记为原子值并保留原始身份,空值直接透传 */
62
+ declare function ref<T extends object | null | undefined>(value: T): T;
63
63
  /**
64
64
  * Create a React Store with automatic tracking and explicit selector support
65
65
  */
package/dist/index.d.mts CHANGED
@@ -58,8 +58,8 @@ interface ExternalStore<TSnapshot> {
58
58
  type ExternalStoreSnapshot<TStore> = TStore extends ExternalStore<infer TSnapshot> ? TSnapshot : never;
59
59
  /** React bindings created for an existing external Store type */
60
60
  type StoreBinding<TStore extends ExternalStore<TSnapshot>, TSnapshot = ExternalStoreSnapshot<TStore>> = readonly [StoreHook<TSnapshot>, ExternalStoreProvider<TStore>, StoreInstanceHook<TStore>];
61
- /** Preserve an exact object identity and compare it as one atomic Store value */
62
- declare function ref<T extends object>(value: T): T;
61
+ /** 将对象标记为原子值并保留原始身份,空值直接透传 */
62
+ declare function ref<T extends object | null | undefined>(value: T): T;
63
63
  /**
64
64
  * Create a React Store with automatic tracking and explicit selector support
65
65
  */
package/dist/index.mjs CHANGED
@@ -223,9 +223,9 @@ function isShallowComparable(value) {
223
223
  }
224
224
  //#endregion
225
225
  //#region src/index.tsx
226
- /** Preserve an exact object identity and compare it as one atomic Store value */
226
+ /** 将对象标记为原子值并保留原始身份,空值直接透传 */
227
227
  function ref(value) {
228
- markToTrack(value, false);
228
+ if (value !== null && value !== void 0) markToTrack(value, false);
229
229
  return value;
230
230
  }
231
231
  const useStoreLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@violetflux/kerros",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "description": "Hook-native state sharing for React with automatic access tracking and focused selectors.",
5
5
  "keywords": [
6
6
  "react",
@@ -96,6 +96,7 @@ The getter does not subscribe and is unavailable before commit, after unmount, o
96
96
  - Return standard `useRef()` and `createRef()` containers directly. They work with DOM refs, `forwardRef`, and `useImperativeHandle` in React 17, 18, and 19; do not wrap them by default.
97
97
  - React elements and portals are detected lazily and returned as atomic values without a Proxy.
98
98
  - Import `ref` from `@violetflux/kerros` only for a third-party object that cannot tolerate a Proxy or when strict object identity must survive the tracked snapshot.
99
+ - `ref(value)` accepts `object | null | undefined` and preserves the exact input type. Pass optional objects directly; `null` and `undefined` are returned unchanged without marking.
99
100
  - `ref(value)`, `Map`, `Set`, and class instances are non-reactive internally. Publish a new containing-field reference for observable changes; changing a React ref's `.current` also does not rerender.
100
101
 
101
102
  ## Advanced external Store binding