Skip to content

Commit b735d84

Browse files
committed
feat: added support for immer
1 parent ed82551 commit b735d84

9 files changed

Lines changed: 1441 additions & 1842 deletions

File tree

dist/index.d.mts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
import { Draft } from 'immer';
2+
13
declare function ripplePrimitive<T>(initial: T): RippleInterface<T>;
24

5+
interface RippleWithImmerUpdate<T> extends RippleInterface<T> {
6+
update(recipe: (draft: Draft<T>) => void | Promise<void>): Promise<void>;
7+
}
38
interface RippleInterface<T> {
49
value: T;
510
subscribe: (cb: () => void, selector?: (v: T) => unknown) => () => void;
@@ -10,6 +15,7 @@ interface RippleFunctionInterface {
1015
<T>(initial: T): RippleInterface<T>;
1116
proxy: <T extends object>(initial: T) => RippleInterface<T>;
1217
primitive: typeof ripplePrimitive;
18+
immer: <T extends object>(initial: T) => RippleWithImmerUpdate<T>;
1319
}
1420

1521
type HandlerType = (payload?: any, tools?: {

dist/index.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
import { Draft } from 'immer';
2+
13
declare function ripplePrimitive<T>(initial: T): RippleInterface<T>;
24

5+
interface RippleWithImmerUpdate<T> extends RippleInterface<T> {
6+
update(recipe: (draft: Draft<T>) => void | Promise<void>): Promise<void>;
7+
}
38
interface RippleInterface<T> {
49
value: T;
510
subscribe: (cb: () => void, selector?: (v: T) => unknown) => () => void;
@@ -10,6 +15,7 @@ interface RippleFunctionInterface {
1015
<T>(initial: T): RippleInterface<T>;
1116
proxy: <T extends object>(initial: T) => RippleInterface<T>;
1217
primitive: typeof ripplePrimitive;
18+
immer: <T extends object>(initial: T) => RippleWithImmerUpdate<T>;
1319
}
1420

1521
type HandlerType = (payload?: any, tools?: {

dist/index.js

Lines changed: 695 additions & 918 deletions
Large diffs are not rendered by default.

dist/index.mjs

Lines changed: 695 additions & 918 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 14 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@
1212
"devDependencies": {
1313
"@preact/signals": "^2.2.0",
1414
"@types/react": "^19.1.8",
15+
"prettier": "3.6.2",
1516
"react": "^19.1.0",
1617
"react-dom": "^19.1.0",
1718
"tsup": "^8.5.0",
1819
"typescript": "^5.8.3",
19-
"prettier": "3.6.2"
20+
"immer": "^10.1.1"
2021
},
2122
"exports": {
2223
".": {

src/core/ripple.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
1-
export { computed, effect } from "@preact/signals";
21
import {
32
RippleFunctionInterface,
43
RippleInterface,
54
} from "../interfaces/ripple.interface";
65
import { ripplePrimitive } from "../utils/ripplePrimitive";
76
import { rippleObject } from "../utils/rippleObject";
87
import { rippleProxy } from "../utils/rippleProxy";
8+
import { createImmerStore } from "../utils/immer";
99

1010
export const ripple = function <T>(initial: T): RippleInterface<T> {
1111
return isObject(initial) ? rippleObject(initial) : ripplePrimitive(initial);
1212
} as RippleFunctionInterface;
1313

14-
function isObject(value: unknown): value is object | Array<any> {
15-
return (typeof value === "object" && value !== null) || Array.isArray(value);
14+
function isObject(value: unknown): value is object | any[] {
15+
return typeof value === "object" && value !== null;
1616
}
1717

1818
Object.assign(ripple, {
1919
proxy: rippleProxy,
2020
primitive: ripplePrimitive,
2121
object: rippleObject,
22+
immer: createImmerStore,
2223
});

src/interfaces/ripple.interface.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
import { ripplePrimitive } from "../utils/ripplePrimitive";
2+
import type { Draft } from "immer";
3+
4+
interface RippleWithImmerUpdate<T> extends RippleInterface<T> {
5+
update(recipe: (draft: Draft<T>) => void | Promise<void>): Promise<void>;
6+
}
27

38
export interface RippleInterface<T> {
49
value: T;
@@ -11,4 +16,5 @@ export interface RippleFunctionInterface {
1116
<T>(initial: T): RippleInterface<T>;
1217
proxy: <T extends object>(initial: T) => RippleInterface<T>;
1318
primitive: typeof ripplePrimitive;
19+
immer: <T extends object>(initial: T) => RippleWithImmerUpdate<T>;
1420
}

src/utils/immer.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { ripplePrimitive } from "./ripplePrimitive";
2+
import { produce, Draft } from "immer";
3+
4+
export function createImmerStore<T extends object>(initial: T) {
5+
const root = ripplePrimitive<T>(initial);
6+
7+
function update(recipe: (draft: Draft<T>) => void) {
8+
const next = produce(root.value, recipe);
9+
if (next !== root.value) root.value = next;
10+
}
11+
12+
return Object.assign(root, { update });
13+
}

0 commit comments

Comments
 (0)