atom.io 0.0.0

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.md ADDED
@@ -0,0 +1,30 @@
1
+ # MVP
2
+ - [x] atoms and selectors
3
+ - [x] implicit store
4
+ - [x] readonly selectors
5
+ - [x] settable selectors
6
+ - [x] safe recursive update propagation
7
+ - [x] safely expose atoms and selectors
8
+ - [x] give atoms and selectors separate types with a common base
9
+ - [x] utility function to pass logger to your store
10
+ - [x] selector memoization
11
+ - [x] atom and selector families
12
+ - [x] atom effects
13
+ - [x] transactions
14
+
15
+ # Features
16
+ - [ ] atom default as function
17
+ - [ ] atom default as promise
18
+ - [ ] resettable atoms
19
+ - [ ] resettable selectors
20
+ - [ ] optional default value for atoms
21
+ - [ ] optional state keys
22
+ - [ ] subscribe to transactions
23
+ - [ ] logging levels (debug, info, warn, error)
24
+
25
+ # Performance Enhancements
26
+ - [ ] refactor selector dependencies to be asymmetrical
27
+ this would permit us to rebuild the dependency graph on every update,
28
+ meaning more efficient memoization
29
+ - [ ] only propagate updates downstream to selectors with an active subscription
30
+ - [ ] trampoline for recursive propagation
@@ -0,0 +1,257 @@
1
+ import * as Rx from 'rxjs';
2
+ import { Hamt } from 'hamt_plus';
3
+ import { Refinement } from 'fp-ts/Refinement';
4
+
5
+ type Primitive = boolean | number | string | null;
6
+ type Serializable = Primitive | Readonly<{
7
+ [key: string]: Serializable;
8
+ }> | ReadonlyArray<Serializable>;
9
+ type JsonObj<Key extends string = string, Value extends Serializable = Serializable> = Record<Key, Value>;
10
+ type JsonArr<Element extends Serializable = Serializable> = ReadonlyArray<Element>;
11
+ type Json = JsonArr | JsonObj | Primitive;
12
+
13
+ type Identified = {
14
+ id: string;
15
+ };
16
+
17
+ declare const RELATION_TYPES: readonly ["1:1", "1:n", "n:n"];
18
+ type RelationType = (typeof RELATION_TYPES)[number];
19
+ type RelationData<CONTENT extends JsonObj | null = null> = {
20
+ contents: JsonObj<string, CONTENT>;
21
+ relations: JsonObj<string, string[]>;
22
+ relationType: RelationType;
23
+ };
24
+
25
+ type NullSafeUnion<Base, Extension> = Extension extends null ? Base : Base & Extension;
26
+ type NullSafeRest<MaybeArg> = MaybeArg extends null ? [] | [undefined] : [MaybeArg];
27
+
28
+ declare class Join<CONTENT extends JsonObj | null = null> implements RelationData<CONTENT> {
29
+ readonly relationType: `1:1` | `1:n` | `n:n`;
30
+ readonly relations: Record<string, string[]>;
31
+ readonly contents: Record<string, CONTENT>;
32
+ constructor(json?: Partial<RelationData<CONTENT>>);
33
+ toJSON(): RelationData<CONTENT>;
34
+ static fromJSON<CONTENT extends JsonObj | null = null>(json: Json, isContent?: Refinement<unknown, CONTENT>): Join<CONTENT>;
35
+ getRelatedId(id: string): string | undefined;
36
+ getRelatedIds(id: string): string[];
37
+ getContent(idA: string, idB: string): CONTENT | undefined;
38
+ getRelationEntries(id: string): [string, CONTENT][];
39
+ getRelationRecord(id: string): Record<string, CONTENT>;
40
+ getRelation(id: string): NullSafeUnion<Identified, CONTENT> | undefined;
41
+ getRelations(id: string): NullSafeUnion<Identified, CONTENT>[];
42
+ setRelations(id: string, relations: NullSafeUnion<Identified, CONTENT>[]): Join<CONTENT>;
43
+ set(idA: string, idB: string, ...rest: NullSafeRest<CONTENT>): Join<CONTENT>;
44
+ remove(idA: string, idB?: string): Join<CONTENT>;
45
+ }
46
+
47
+ interface Store {
48
+ valueMap: Hamt<any, string>;
49
+ selectorGraph: Join;
50
+ selectors: Hamt<Selector<any>, string>;
51
+ readonlySelectors: Hamt<ReadonlySelector<any>, string>;
52
+ atoms: Hamt<Atom<any>, string>;
53
+ operation: {
54
+ open: false;
55
+ } | {
56
+ open: true;
57
+ done: Set<string>;
58
+ prev: Hamt<any, string>;
59
+ };
60
+ transaction: {
61
+ open: false;
62
+ } | {
63
+ open: true;
64
+ prev: Pick<Store, `atoms` | `readonlySelectors` | `selectorGraph` | `selectors` | `valueMap`>;
65
+ };
66
+ config: {
67
+ name: string;
68
+ logger: Pick<Console, `error` | `info` | `warn`> | null;
69
+ };
70
+ }
71
+ declare const createStore: (name: string) => Store;
72
+ declare const IMPLICIT: {
73
+ STORE_INTERNAL: Store | undefined;
74
+ readonly STORE: Store;
75
+ };
76
+ declare const configure: (config: Partial<Store[`config`]>, store?: Store) => void;
77
+ declare const clearStore: (store?: Store) => void;
78
+
79
+ declare const getCachedState: <T>(state: Atom<T> | Selector<T> | ReadonlySelector<T>, store?: Store) => T;
80
+ declare const getSelectorState: <T>(selector: Selector<T> | ReadonlySelector<T>) => T;
81
+ declare function withdraw<T>(token: AtomToken<T>, store: Store): Atom<T>;
82
+ declare function withdraw<T>(token: SelectorToken<T>, store: Store): Selector<T>;
83
+ declare function withdraw<T>(token: StateToken<T>, store: Store): Atom<T> | Selector<T>;
84
+ declare function withdraw<T>(token: ReadonlyValueToken<T>, store: Store): ReadonlySelector<T>;
85
+ declare function withdraw<T>(token: ReadonlyValueToken<T> | StateToken<T>, store: Store): Atom<T> | ReadonlySelector<T> | Selector<T>;
86
+ declare function deposit<T>(state: Atom<T>): AtomToken<T>;
87
+ declare function deposit<T>(state: Selector<T>): SelectorToken<T>;
88
+ declare function deposit<T>(state: Atom<T> | Selector<T>): StateToken<T>;
89
+ declare function deposit<T>(state: ReadonlySelector<T>): ReadonlyValueToken<T>;
90
+ declare function deposit<T>(state: Atom<T> | ReadonlySelector<T> | Selector<T>): ReadonlyValueToken<T> | StateToken<T>;
91
+ declare const getState__INTERNAL: <T>(state: Atom<T> | Selector<T> | ReadonlySelector<T>, store?: Store) => T;
92
+
93
+ declare const propagateChanges: <T>(state: Atom<T> | Selector<T>, store?: Store) => void;
94
+ declare const setAtomState: <T>(atom: Atom<T>, next: T | ((oldValue: T) => T), store?: Store) => void;
95
+ declare const setSelectorState: <T>(selector: Selector<T>, next: T | ((oldValue: T) => T), store?: Store) => void;
96
+ declare const setState__INTERNAL: <T>(token: StateToken<T>, value: T | ((oldValue: T) => T), store?: Store) => void;
97
+
98
+ declare const finishAction: (store: Store) => void;
99
+ declare const startAction: (store: Store) => void;
100
+ declare const isDone: (key: string, store?: Store) => boolean;
101
+ declare const markDone: (key: string, store?: Store) => void;
102
+ declare const recall: <T>(state: Atom<T> | Selector<T> | ReadonlySelector<T>, store?: Store) => T;
103
+
104
+ declare const finishTransaction: (store: Store) => void;
105
+ declare const startTransaction: (store: Store) => void;
106
+ declare const abortTransaction: (store: Store) => void;
107
+
108
+ type Atom<T> = {
109
+ key: string;
110
+ subject: Rx.Subject<{
111
+ newValue: T;
112
+ oldValue: T;
113
+ }>;
114
+ default: T;
115
+ };
116
+ type Selector<T> = {
117
+ key: string;
118
+ subject: Rx.Subject<{
119
+ newValue: T;
120
+ oldValue: T;
121
+ }>;
122
+ get: () => T;
123
+ set: (newValue: T | ((oldValue: T) => T)) => void;
124
+ };
125
+ type ReadonlySelector<T> = Omit<Selector<T>, `set`>;
126
+
127
+ type index_Atom<T> = Atom<T>;
128
+ declare const index_IMPLICIT: typeof IMPLICIT;
129
+ type index_ReadonlySelector<T> = ReadonlySelector<T>;
130
+ type index_Selector<T> = Selector<T>;
131
+ type index_Store = Store;
132
+ declare const index_abortTransaction: typeof abortTransaction;
133
+ declare const index_clearStore: typeof clearStore;
134
+ declare const index_configure: typeof configure;
135
+ declare const index_createStore: typeof createStore;
136
+ declare const index_deposit: typeof deposit;
137
+ declare const index_finishAction: typeof finishAction;
138
+ declare const index_finishTransaction: typeof finishTransaction;
139
+ declare const index_getCachedState: typeof getCachedState;
140
+ declare const index_getSelectorState: typeof getSelectorState;
141
+ declare const index_getState__INTERNAL: typeof getState__INTERNAL;
142
+ declare const index_isDone: typeof isDone;
143
+ declare const index_markDone: typeof markDone;
144
+ declare const index_propagateChanges: typeof propagateChanges;
145
+ declare const index_recall: typeof recall;
146
+ declare const index_setAtomState: typeof setAtomState;
147
+ declare const index_setSelectorState: typeof setSelectorState;
148
+ declare const index_setState__INTERNAL: typeof setState__INTERNAL;
149
+ declare const index_startAction: typeof startAction;
150
+ declare const index_startTransaction: typeof startTransaction;
151
+ declare const index_withdraw: typeof withdraw;
152
+ declare namespace index {
153
+ export {
154
+ index_Atom as Atom,
155
+ index_IMPLICIT as IMPLICIT,
156
+ index_ReadonlySelector as ReadonlySelector,
157
+ index_Selector as Selector,
158
+ index_Store as Store,
159
+ index_abortTransaction as abortTransaction,
160
+ index_clearStore as clearStore,
161
+ index_configure as configure,
162
+ index_createStore as createStore,
163
+ index_deposit as deposit,
164
+ index_finishAction as finishAction,
165
+ index_finishTransaction as finishTransaction,
166
+ index_getCachedState as getCachedState,
167
+ index_getSelectorState as getSelectorState,
168
+ index_getState__INTERNAL as getState__INTERNAL,
169
+ index_isDone as isDone,
170
+ index_markDone as markDone,
171
+ index_propagateChanges as propagateChanges,
172
+ index_recall as recall,
173
+ index_setAtomState as setAtomState,
174
+ index_setSelectorState as setSelectorState,
175
+ index_setState__INTERNAL as setState__INTERNAL,
176
+ index_startAction as startAction,
177
+ index_startTransaction as startTransaction,
178
+ index_withdraw as withdraw,
179
+ };
180
+ }
181
+
182
+ type Effectors<T> = {
183
+ setSelf: <V extends T>(next: V | ((oldValue: T) => V)) => void;
184
+ onSet: (callback: (options: {
185
+ newValue: T;
186
+ oldValue: T;
187
+ }) => void) => void;
188
+ };
189
+ type AtomEffect<T> = (tools: Effectors<T>) => void;
190
+ type AtomOptions<T> = {
191
+ key: string;
192
+ default: T;
193
+ effects?: AtomEffect<T>[];
194
+ };
195
+ declare const atom: <T>(options: AtomOptions<T>, store?: Store) => AtomToken<T>;
196
+ type AtomFamilyOptions<T, K extends Serializable> = {
197
+ key: string;
198
+ default: T | ((key: K) => T);
199
+ effects?: (key: K) => AtomEffect<T>[];
200
+ };
201
+ declare const atomFamily: <T, K extends Serializable>(options: AtomFamilyOptions<T, K>, store?: Store) => (key: K) => AtomToken<T>;
202
+
203
+ type ƒn = (...parameters: any[]) => any;
204
+ type Transactors = {
205
+ get: <S>(state: ReadonlyValueToken<S> | StateToken<S>) => S;
206
+ set: <S>(state: StateToken<S>, newValue: S | ((oldValue: S) => S)) => void;
207
+ };
208
+ type ReadonlyTransactors = Pick<Transactors, `get`>;
209
+ type Action<ƒ extends ƒn> = (transactors: Transactors, ...parameters: Parameters<ƒ>) => ReturnType<ƒ>;
210
+ type TransactionOptions<ƒ extends ƒn> = {
211
+ key: string;
212
+ do: Action<ƒ>;
213
+ };
214
+ declare const transaction: <ƒ extends ƒn>(options: TransactionOptions<ƒ>, store?: Store) => ((...parameters: Parameters<ƒ>) => ReturnType<ƒ>) & {
215
+ key: string;
216
+ };
217
+
218
+ type SelectorOptions<T> = {
219
+ key: string;
220
+ get: (readonlyTransactors: ReadonlyTransactors) => T;
221
+ set: (transactors: Transactors, newValue: T) => void;
222
+ };
223
+ type ReadonlySelectorOptions<T> = Omit<SelectorOptions<T>, `set`>;
224
+ declare function selector<T>(options: SelectorOptions<T>, store?: Store): SelectorToken<T>;
225
+ declare function selector<T>(options: ReadonlySelectorOptions<T>, store?: Store): ReadonlyValueToken<T>;
226
+ type SelectorFamilyOptions<T, K extends Serializable> = {
227
+ key: string;
228
+ get: (key: K) => (readonlyTransactors: ReadonlyTransactors) => T;
229
+ set: (key: K) => (transactors: Transactors, newValue: T) => void;
230
+ };
231
+ type ReadonlySelectorFamilyOptions<T, K extends Serializable> = Omit<SelectorFamilyOptions<T, K>, `set`>;
232
+ declare function selectorFamily<T, K extends Serializable>(options: SelectorFamilyOptions<T, K>, store?: Store): (key: K) => SelectorToken<T>;
233
+ declare function selectorFamily<T, K extends Serializable>(options: ReadonlySelectorFamilyOptions<T, K>, store?: Store): (key: K) => ReadonlyValueToken<T>;
234
+ declare const registerSelector: (selectorKey: string, store?: Store) => Transactors;
235
+
236
+ interface AtomToken<_> {
237
+ key: string;
238
+ type: `atom`;
239
+ }
240
+ interface SelectorToken<_> {
241
+ key: string;
242
+ type: `selector`;
243
+ }
244
+ type StateToken<T> = AtomToken<T> | SelectorToken<T>;
245
+ interface ReadonlyValueToken<_> {
246
+ key: string;
247
+ type: `readonly_selector`;
248
+ }
249
+ declare const getState: <T>(token: ReadonlyValueToken<T> | StateToken<T>, store?: Store) => T;
250
+ declare const setState: <State, Value extends State>(state: StateToken<State>, value: Value | ((oldValue: State) => Value), store?: Store) => void;
251
+ type Observe<T> = (change: {
252
+ newValue: T;
253
+ oldValue: T;
254
+ }) => void;
255
+ declare const subscribe: <T>(token: ReadonlyValueToken<T> | StateToken<T>, observe: Observe<T>, store?: Store) => (() => void);
256
+
257
+ export { Action, AtomEffect, AtomFamilyOptions, AtomOptions, AtomToken, Effectors, Observe, ReadonlySelectorFamilyOptions, ReadonlySelectorOptions, ReadonlyTransactors, ReadonlyValueToken, SelectorFamilyOptions, SelectorOptions, SelectorToken, StateToken, TransactionOptions, Transactors, index as __INTERNAL__, atom, atomFamily, configure, getState, registerSelector, selector, selectorFamily, setState, subscribe, transaction, ƒn };