You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
27 lines
855 B
27 lines
855 B
import { ActiveSymbol } from './symbols.ts';
|
|
import { isState } from './guards.ts';
|
|
import type { Active } from './types.ts';
|
|
|
|
/**
|
|
* Wraps a reactive container in a readonly view, preventing external mutation.
|
|
* If the container is already readonly, it is returned as-is with no extra wrapping.
|
|
*
|
|
* @example
|
|
* const count = state(0); // State<number> — mutable
|
|
* const roCount = readonly(count); // Reactive<number> — readonly
|
|
*
|
|
* roCount.current = 1; // TS error: cannot assign to readonly property
|
|
* count.current = 1; // still works — original is unaffected
|
|
*/
|
|
export function readonly<T>(source: Active<T>): Active<T> {
|
|
// Already readonly — return as-is, no unnecessary wrapping.
|
|
if (!isState(source)) return source;
|
|
|
|
return {
|
|
[ActiveSymbol]: true,
|
|
get current() {
|
|
return source.current;
|
|
}
|
|
};
|
|
}
|