chem-rx 0.0.23 → 0.2.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/src/Atom.ts DELETED
@@ -1,374 +0,0 @@
1
- import {
2
- BehaviorSubject,
3
- combineLatest,
4
- distinctUntilChanged,
5
- distinctUntilKeyChanged,
6
- isObservable,
7
- map,
8
- Observable,
9
- OperatorFunction,
10
- Subscription,
11
- } from "rxjs";
12
- import { OverloadedParameters } from "./types";
13
-
14
- export type AtomTuple<T> = {
15
- [K in keyof T]: ReadOnlyAtom<T[K]>;
16
- };
17
-
18
- export class ReadOnlyAtom<T> {
19
- _behavior$: BehaviorSubject<T>;
20
-
21
- _parent?: BehaviorSubject<T>[];
22
- _bonds: BehaviorSubject<T>[] = [];
23
-
24
- _fromObservable: Observable<T> | null = null;
25
- _fromObservableSubscription: Subscription | null = null;
26
-
27
- constructor(_value: T | Observable<T>) {
28
- if (isObservable(_value)) {
29
- this._fromObservable = _value;
30
- this._behavior$ = new BehaviorSubject<T>(null!);
31
- this._fromObservableSubscription = _value.subscribe((value) => {
32
- this._behavior$.next(value);
33
- });
34
- } else {
35
- // if it's just a value just use a regular behavior subject
36
- this._behavior$ = new BehaviorSubject<T>(_value);
37
- }
38
- }
39
-
40
- // taken from Observable
41
- pipe(): ReadOnlyAtom<T>;
42
- pipe<A>(op1: OperatorFunction<T, A>): ReadOnlyAtom<A>;
43
- pipe<A, B>(
44
- op1: OperatorFunction<T, A>,
45
- op2: OperatorFunction<A, B>
46
- ): ReadOnlyAtom<B>;
47
- pipe<A, B, C>(
48
- op1: OperatorFunction<T, A>,
49
- op2: OperatorFunction<A, B>,
50
- op3: OperatorFunction<B, C>
51
- ): ReadOnlyAtom<C>;
52
- pipe<A, B, C, D>(
53
- op1: OperatorFunction<T, A>,
54
- op2: OperatorFunction<A, B>,
55
- op3: OperatorFunction<B, C>,
56
- op4: OperatorFunction<C, D>
57
- ): ReadOnlyAtom<D>;
58
- pipe<A, B, C, D, E>(
59
- op1: OperatorFunction<T, A>,
60
- op2: OperatorFunction<A, B>,
61
- op3: OperatorFunction<B, C>,
62
- op4: OperatorFunction<C, D>,
63
- op5: OperatorFunction<D, E>
64
- ): ReadOnlyAtom<E>;
65
- pipe<A, B, C, D, E, F>(
66
- op1: OperatorFunction<T, A>,
67
- op2: OperatorFunction<A, B>,
68
- op3: OperatorFunction<B, C>,
69
- op4: OperatorFunction<C, D>,
70
- op5: OperatorFunction<D, E>,
71
- op6: OperatorFunction<E, F>
72
- ): ReadOnlyAtom<F>;
73
- pipe<A, B, C, D, E, F, G>(
74
- op1: OperatorFunction<T, A>,
75
- op2: OperatorFunction<A, B>,
76
- op3: OperatorFunction<B, C>,
77
- op4: OperatorFunction<C, D>,
78
- op5: OperatorFunction<D, E>,
79
- op6: OperatorFunction<E, F>,
80
- op7: OperatorFunction<F, G>
81
- ): ReadOnlyAtom<G>;
82
- pipe<A, B, C, D, E, F, G, H>(
83
- op1: OperatorFunction<T, A>,
84
- op2: OperatorFunction<A, B>,
85
- op3: OperatorFunction<B, C>,
86
- op4: OperatorFunction<C, D>,
87
- op5: OperatorFunction<D, E>,
88
- op6: OperatorFunction<E, F>,
89
- op7: OperatorFunction<F, G>,
90
- op8: OperatorFunction<G, H>
91
- ): ReadOnlyAtom<H>;
92
- pipe<A, B, C, D, E, F, G, H, I>(
93
- op1: OperatorFunction<T, A>,
94
- op2: OperatorFunction<A, B>,
95
- op3: OperatorFunction<B, C>,
96
- op4: OperatorFunction<C, D>,
97
- op5: OperatorFunction<D, E>,
98
- op6: OperatorFunction<E, F>,
99
- op7: OperatorFunction<F, G>,
100
- op8: OperatorFunction<G, H>,
101
- op9: OperatorFunction<H, I>
102
- ): ReadOnlyAtom<I>;
103
- pipe<A, B, C, D, E, F, G, H, I>(
104
- op1: OperatorFunction<T, A>,
105
- op2: OperatorFunction<A, B>,
106
- op3: OperatorFunction<B, C>,
107
- op4: OperatorFunction<C, D>,
108
- op5: OperatorFunction<D, E>,
109
- op6: OperatorFunction<E, F>,
110
- op7: OperatorFunction<F, G>,
111
- op8: OperatorFunction<G, H>,
112
- op9: OperatorFunction<H, I>,
113
- ...operations: OperatorFunction<any, any>[]
114
- ): ReadOnlyAtom<unknown>;
115
- pipe(
116
- ...operations: OverloadedParameters<Observable<T>["pipe"]>
117
- ): ReadOnlyAtom<any> {
118
- // @ts-ignore can't match overloaded function
119
- const observable = this._behavior$.pipe(...operations);
120
- const newAtom = new ReadOnlyAtom(observable);
121
-
122
- return newAtom;
123
- }
124
-
125
- derive<A>(deriveFn: (value: T, index: number) => A): ReadOnlyAtom<A> {
126
- return this.pipe(map(deriveFn));
127
- }
128
-
129
- subscribe(...params: Parameters<BehaviorSubject<T>["subscribe"]>) {
130
- return this._behavior$.subscribe(...params);
131
- }
132
-
133
- value() {
134
- return this._behavior$.getValue();
135
- }
136
-
137
- // not needed?
138
- dispose() {
139
- this._fromObservableSubscription?.unsubscribe();
140
- }
141
-
142
- get<K extends keyof T>(
143
- key: K
144
- // key: T extends (infer W)[]
145
- // ? number
146
- // : T extends { [key in keyof T]: infer W }
147
- // ? keyof T
148
- // : undefined
149
- ): T extends (infer W)[] ? T[number] : T[K] {
150
- const val = this.value() as T;
151
- return val?.[key] as T extends (infer W)[] ? T[number] : T[K];
152
- }
153
-
154
- select<K extends keyof T>(
155
- key: K
156
- ): T[K] extends (infer W)[] ? ArrayAtom<W> : BaseAtom<T[K]> {
157
- // console.log("key", key);
158
- const newObs = this._behavior$.pipe(
159
- distinctUntilChanged((a, b) => {
160
- if (a === b) return true;
161
- if (a && b && a[key] === b[key]) return true;
162
- return false;
163
- }),
164
- map((k) => {
165
- // console.log("insideee", k, key);
166
-
167
- return k?.[key];
168
- })
169
- );
170
- // console.log("obs", newObs);
171
- // Can't get typescript to recognize the types here so I'm cheating
172
- return Atom(newObs) as unknown as T[K] extends (infer W)[]
173
- ? ArrayAtom<W>
174
- : BaseAtom<T[K]>;
175
- }
176
- }
177
-
178
- export class BaseAtom<T> extends ReadOnlyAtom<T> {
179
- next(nextVal: T) {
180
- this._behavior$.next(nextVal);
181
- }
182
-
183
- set(nextKey: keyof T, nextValue: T[keyof T]) {
184
- this._behavior$.next({
185
- ...this._behavior$.getValue(),
186
- [nextKey]: nextValue,
187
- });
188
- }
189
- }
190
-
191
- export class NullableBaseAtom<T> extends BaseAtom<T> {
192
- constructor(_value?: T | Observable<T>) {
193
- if (_value != null) {
194
- super(_value);
195
- } else {
196
- // @ts-ignore
197
- super(undefined);
198
- }
199
- }
200
-
201
- // @ts-ignore
202
- get<K extends keyof T>(
203
- key: K
204
- // key: T extends (infer W)[]
205
- // ? number
206
- // : T extends { [key in keyof T]: infer W }
207
- // ? keyof T
208
- // : undefined
209
- ): (T extends (infer W)[] ? T[number] : T[K]) | undefined {
210
- return super.get(key);
211
- }
212
-
213
- // @ts-ignore
214
- select<K extends keyof T>(
215
- key: K
216
- ): T extends (infer W)[] ? ArrayAtom<W> : NullableBaseAtom<T[K]> {
217
- // @ts-ignore
218
- return super.select(key);
219
- }
220
-
221
- next(nextVal: T | null | undefined) {
222
- // @ts-ignore
223
- super.next(nextVal);
224
- }
225
-
226
- reset() {
227
- // @ts-ignore
228
- super.next(undefined);
229
- }
230
- }
231
-
232
- export class ArrayAtom<T> extends BaseAtom<T[]> {
233
- constructor(initialValue?: T[]) {
234
- if (initialValue) {
235
- super(initialValue);
236
- } else {
237
- super([]);
238
- }
239
- }
240
-
241
- push(nextVal: T) {
242
- this._behavior$.next([...this._behavior$.getValue(), nextVal]);
243
- }
244
- }
245
-
246
- //
247
- // export class ReadOnlyObjectAtom<
248
- // T extends {
249
- // [key in K]: V;
250
- // },
251
- // K extends string | number | symbol = keyof T,
252
- // V = T[K]
253
- // > extends ReadOnlyAtom<T> {
254
- // get(nextKey: K) {
255
- // return this.value()[nextKey];
256
- // }
257
- //
258
- // select<K extends keyof T>(
259
- // key: K
260
- // ): T[K] extends (infer W)[]
261
- // ? ArrayAtom<W>
262
- // : T[K] extends { [key in infer L]?: infer W }
263
- // ? ObjectAtom<T[K]>
264
- // : BaseAtom<T> {
265
- // const newObs = this._behavior$.pipe(
266
- // distinctUntilKeyChanged(key),
267
- // map((k) => k?.[key])
268
- // );
269
- // // Can't get typescript to recognize the types here so I'm cheating
270
- // return Atom(newObs) as unknown as T[K] extends (infer W)[]
271
- // ? ArrayAtom<W>
272
- // : T[K] extends { [key in infer L]?: infer W }
273
- // ? ObjectAtom<T[K]>
274
- // : BaseAtom<T>;
275
- // }
276
- // }
277
- //
278
- // export class ObjectAtom<
279
- // T extends
280
- // | {
281
- // [key in K]: V;
282
- // }
283
- // | null,
284
- // K extends string | number | symbol = keyof T,
285
- // V = T extends { [key in K]: infer W } ? T[K] : null
286
- // > extends ReadOnlyAtom<T> {
287
- // set(nextKey: K, nextValue: V) {
288
- // this._behavior$.next({
289
- // ...this._behavior$.getValue(),
290
- // [nextKey]: nextValue,
291
- // });
292
- // }
293
- // }
294
-
295
- // catch-all for developers
296
- // export type AnyAtom<T> = BaseAtom<T> | ArrayAtom<T> | ObjectAtom<T>;
297
-
298
- // observable<array> type
299
- export function Atom<T extends any[]>(
300
- value?: Observable<T>
301
- ): ArrayAtom<T[number]>;
302
-
303
- // observable<object> type
304
- export function Atom<T>(
305
- value: T extends {
306
- [key in keyof T]: infer V;
307
- }
308
- ? Observable<T>
309
- : never
310
- ): BaseAtom<T>;
311
-
312
- // nullable observable<object> type
313
- export function Atom<T>(
314
- value?: T extends {
315
- [key in keyof T]: infer V;
316
- }
317
- ? Observable<T>
318
- : never
319
- ): NullableBaseAtom<T>;
320
-
321
- // observable type (primitive)
322
- export function Atom<T>(
323
- value?: T extends { [key: string]: infer V } | any[] ? never : Observable<T>
324
- ): BaseAtom<T>;
325
-
326
- // nullable observable type (primitive)
327
- export function Atom<T>(
328
- value?: T extends { [key: string]: infer V } | any[] ? never : Observable<T>
329
- ): NullableBaseAtom<T>;
330
-
331
- // array type
332
- export function Atom<T extends any[]>(value?: T): ArrayAtom<T[number]>;
333
-
334
- // object type
335
- export function Atom<T extends { [key: string]: T[keyof T] }>(
336
- value: T
337
- ): BaseAtom<T>;
338
-
339
- // nullable (unitialized) object type
340
- export function Atom<T extends { [key: string]: T[keyof T] }>(
341
- value?: T
342
- ): NullableBaseAtom<T>;
343
-
344
- // primitive type
345
- export function Atom<T>(value: T): BaseAtom<T>;
346
-
347
- // nullable (unitialized) primitive type
348
- export function Atom<T>(value?: T): NullableBaseAtom<T>;
349
-
350
- // readonly type
351
- export function Atom<T>(value: T, readOnly?: boolean): ReadOnlyAtom<T>;
352
-
353
- // function definition
354
- export function Atom<T>(_value: T, readOnly: boolean = false) {
355
- let atom;
356
- if (readOnly) {
357
- atom = new ReadOnlyAtom(_value);
358
- } else if (Array.isArray(_value)) {
359
- atom = new ArrayAtom<T>(_value); // For arrays
360
- } else if (_value == null) {
361
- atom = new NullableBaseAtom();
362
- } else {
363
- atom = new BaseAtom(_value); // For other types
364
- }
365
- return atom;
366
- }
367
-
368
- Atom.combine = <A extends readonly unknown[]>(
369
- ...atoms: readonly [...AtomTuple<A>]
370
- ): ReadOnlyAtom<A> => {
371
- const observable = combineLatest(...atoms.map((a) => a._behavior$));
372
- const newAtom = new ReadOnlyAtom(observable) as unknown as ReadOnlyAtom<A>;
373
- return newAtom;
374
- };
package/src/Signal.ts DELETED
@@ -1,38 +0,0 @@
1
- import { Subject, Subscription } from "rxjs";
2
-
3
- export class Signal<T = any> {
4
- private _subjects: Map<string, Subject<T>>;
5
- private _defaultSubject: Subject<T>;
6
-
7
- constructor() {
8
- this._subjects = new Map();
9
- this._defaultSubject = new Subject<T>();
10
- }
11
-
12
- ping(value: T, id?: string) {
13
- if (id && this._subjects.has(id)) {
14
- // If an ID is provided and exists, notify only that subscription.
15
- this._subjects.get(id)?.next(value);
16
- } else {
17
- // No ID provided, notify all default subscribers.
18
- this._defaultSubject.next(value);
19
- // Additionally, notify all subscriptions as a broadcast.
20
- this._subjects.forEach((subject) => subject.next(value));
21
- }
22
- }
23
-
24
- subscribe(callback: (value: T) => void, id?: string): Subscription {
25
- if (id) {
26
- // If an ID is provided, subscribe to the specific ID.
27
- if (!this._subjects.has(id)) {
28
- this._subjects.set(id, new Subject<T>());
29
- }
30
- return this._subjects.get(id)!.subscribe(callback);
31
- } else {
32
- // No ID provided, subscribe to the default subject.
33
- return this._defaultSubject.subscribe(callback);
34
- }
35
- }
36
-
37
- // Optionally, implement unsubscribe logic to manage subscriptions.
38
- }
package/src/types.ts DELETED
@@ -1,66 +0,0 @@
1
- // Helper types if needed
2
-
3
- class GenericClass<T> {}
4
- export type GetGenericType<C extends GenericClass<any>> =
5
- C extends GenericClass<infer T> ? T : unknown;
6
-
7
- export type KeyOfValueType<T, V> = {
8
- [K in keyof T]: T[K] extends V ? K : never;
9
- }[keyof T];
10
-
11
- export type IsObject<T> = T extends object ? T : never;
12
- export type IsntObject<T> = T extends object ? never : T;
13
- export type IsntFunction<T> = T extends Function ? never : T;
14
-
15
- export type OmitKeysWithNeverValues<T> = {
16
- [K in keyof T as T[K] extends never ? never : K]: T[K];
17
- };
18
-
19
- export function assertUnreachable(_value?: never): never {
20
- throw new Error("Statement should be unreachable");
21
- }
22
-
23
- // https://github.com/microsoft/TypeScript/issues/32164
24
-
25
- type ValidFunction<
26
- Arguments extends unknown[],
27
- ReturnType
28
- > = unknown[] extends Arguments
29
- ? unknown extends ReturnType
30
- ? never
31
- : (...args: Arguments) => ReturnType
32
- : (...args: Arguments) => ReturnType;
33
-
34
- export type Overloads<T extends (...args: unknown[]) => unknown> = T extends {
35
- (...args: infer A1): infer R1;
36
- (...args: infer A2): infer R2;
37
- (...args: infer A3): infer R3;
38
- (...args: infer A4): infer R4;
39
- (...args: infer A5): infer R5;
40
- (...args: infer A6): infer R6;
41
- (...args: infer A7): infer R7;
42
- (...args: infer A8): infer R8;
43
- (...args: infer A9): infer R9;
44
- (...args: infer A10): infer R10;
45
- (...args: infer A11): infer R11;
46
- (...args: infer A12): infer R12;
47
- }
48
- ?
49
- | ValidFunction<A1, R1>
50
- | ValidFunction<A2, R2>
51
- | ValidFunction<A3, R3>
52
- | ValidFunction<A4, R4>
53
- | ValidFunction<A5, R5>
54
- | ValidFunction<A6, R6>
55
- | ValidFunction<A7, R7>
56
- | ValidFunction<A8, R8>
57
- | ValidFunction<A9, R9>
58
- | ValidFunction<A10, R10>
59
- | ValidFunction<A11, R11>
60
- | ValidFunction<A12, R12>
61
- : never;
62
-
63
- export type OverloadedParameters<T extends (...args: any[]) => unknown> =
64
- Parameters<Overloads<T>>;
65
- export type OverloadedReturnType<T extends (...args: any[]) => unknown> =
66
- ReturnType<Overloads<T>>;
package/src/useAtom.ts DELETED
@@ -1,20 +0,0 @@
1
- import { useEffect, useState } from "react";
2
- import { BaseAtom, NullableBaseAtom, ReadOnlyAtom } from "./Atom";
3
-
4
- export function useAtom<T>(
5
- atom: BaseAtom<T> | NullableBaseAtom<T> | ReadOnlyAtom<T>
6
- ): T {
7
- const [value, setValue] = useState<T>(atom.value());
8
-
9
- useEffect(() => {
10
- const subscription = atom.subscribe((val) => {
11
- setValue(val);
12
- });
13
-
14
- return () => {
15
- subscription.unsubscribe();
16
- };
17
- }, [atom]);
18
-
19
- return value;
20
- }
@@ -1,16 +0,0 @@
1
- import { useEffect } from "react";
2
- import { BaseAtom, NullableBaseAtom, ReadOnlyAtom } from "./Atom";
3
-
4
- const hydratedAtomsSet: WeakSet<ReadOnlyAtom<any>> = new WeakSet();
5
-
6
- export function hydrateAtoms(
7
- values: readonly [NullableBaseAtom<any> | BaseAtom<any>, any][],
8
- options?: { force?: boolean }
9
- ) {
10
- for (const [atom, value] of values) {
11
- if (!hydratedAtomsSet.has(atom) || options?.force) {
12
- hydratedAtomsSet.add(atom);
13
- atom._behavior$.next(value);
14
- }
15
- }
16
- }
@@ -1,25 +0,0 @@
1
- import { useEffect, useState } from "react";
2
- import { BaseAtom, NullableBaseAtom, ReadOnlyAtom } from "./Atom";
3
-
4
- export function useSelectAtom<
5
- T extends
6
- | {
7
- [key in K]: V;
8
- },
9
- K extends keyof T,
10
- V = T[K]
11
- >(atom: NullableBaseAtom<T> | BaseAtom<T> | ReadOnlyAtom<T>, key: K): T[K] {
12
- const [value, setValue] = useState<T[K]>(atom.get(key)!);
13
-
14
- useEffect(() => {
15
- const subscription = atom.select(key).subscribe((val) => {
16
- setValue(val as T[K]);
17
- });
18
-
19
- return () => {
20
- subscription.unsubscribe();
21
- };
22
- }, [atom]);
23
-
24
- return value;
25
- }
package/src/useSignal.ts DELETED
@@ -1,24 +0,0 @@
1
- import { useEffect, useState } from "react";
2
- import { Signal } from "./Signal";
3
- import { Subscription } from "rxjs";
4
-
5
- export function useSignal<T>(
6
- signal: Signal<T>,
7
- callback?: (update: T) => void,
8
- id?: string
9
- ) {
10
- useEffect(() => {
11
- // Assuming the signal might not have an initial value method like `atom.value()`,
12
- // If your signal class has a method to get the current/latest value, use it here to initialize.
13
-
14
- let subscription: Subscription;
15
- if (callback) {
16
- subscription = signal.subscribe(callback, id);
17
- }
18
- return () => {
19
- if (subscription) {
20
- subscription.unsubscribe();
21
- }
22
- };
23
- }, [signal, callback, id]);
24
- }