-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbinder.ts
More file actions
111 lines (107 loc) · 2.91 KB
/
binder.ts
File metadata and controls
111 lines (107 loc) · 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import type { Store } from './interface';
import { bindSymbol } from './constant';
import { Internal } from './internal';
export type ExternalStoreAdapterOptions<F = (...args: any[]) => any> = {
/**
* Normalize a third-party store instance into a raw state object plus the
* binding hook used during initialization.
*/
handleState: <T extends object = object>(
state: T
) => {
/**
* Copy of the incoming state object that Coaction should consume.
*/
copyState: T;
/**
* Optional nested key when the adapter exposes a single child object from
* the third-party store.
*/
key?: keyof T;
/**
* Convert the external state object into the raw state shape used by
* Coaction.
*/
bind: (state: T) => T;
};
/**
* Wire Coaction's store lifecycle to the external store implementation.
*/
handleStore: (
/**
* Coaction store wrapper.
*/
store: Store<object>,
/**
* Raw state object returned from `bind`.
*/
rawState: object,
/**
* Original external store state object.
*/
state: object,
/**
* Low-level Coaction adapter hooks used by official bindings.
*/
internal: Internal<object>,
/**
* Optional nested key returned by `handleState`.
*/
key?: string
) => void;
/**
* This phantom field lets callers pin the returned adapter function type
* without affecting runtime behavior.
* @internal
*/
adapterType?: F;
};
const createExternalStoreAdapter = <F = (...args: any[]) => any>({
handleState,
handleStore
}: ExternalStoreAdapterOptions<F>) =>
(<S extends object>(state: S): S => {
const { copyState, key, bind } = handleState(state);
const value = (key ? copyState[key] : copyState) as {
[bindSymbol]: {
handleStore: typeof handleStore;
bind: typeof bind;
};
};
value[bindSymbol] = {
handleStore,
bind
};
return copyState;
}) as F;
/**
* Build an adapter helper for bridging an external store implementation into
* Coaction.
*
* @remarks
* Official bindings use this to integrate stores such as Redux, Jotai, Pinia,
* Zustand, MobX, and Valtio. Binder-backed integrations are whole-store
* adapters; they are not compatible with Coaction slices mode.
*/
export function createBinder<F = (...args: any[]) => any>({
handleState,
handleStore
}: ExternalStoreAdapterOptions<F>) {
return createExternalStoreAdapter<F>({
handleState,
handleStore
});
}
/**
* Define a whole-store adapter for integrating an external state runtime with
* Coaction.
*
* @remarks
* This is the stable 2.x name for adapter authors. `createBinder()` remains as
* a compatibility alias for existing official and community integrations.
*/
export function defineExternalStoreAdapter<F = (...args: any[]) => any>(
options: ExternalStoreAdapterOptions<F>
) {
return createExternalStoreAdapter<F>(options);
}